Reputation: 141
For example say I am looping through a vector of pointers to check multiple objects and perform operations on them. I could do either of the following.
Method 1:
std::vector< Object* >::iterator it;
Object* o;
for (it = objects.begin(); it != objects.end(); ++it)
{
o = (*it)
if(o->GetActive())
{
o->method;
o->method2;
o->method3;
//etc...
}
}
Method 2:
std::vector< Object* >::iterator it;
for (it = objects.begin(); it != objects.end(); ++it)
{
if((*it)->GetActive())
{
(*it)->method;
(*it)->method2;
(*it)->method3;
//etc...
}
}
From what I can see Method 1 has easier readability as dereferencing syntax can often complicate the readability, especially when you are doing something like:
if((*o)->CheckValue((*c)))
But creating local variables would make it much easier to read:
if(o->CheckValue(c))
But you are creating extra variables which would increase the memory cost, right?
What would the differences in performance be?
Upvotes: 0
Views: 493
Reputation: 179819
I would in fact choose another syntax, which makes the choice irrelevant:
for (Object* o : objects)
{
// ... body
}
Upvotes: 1
Reputation: 308196
An optimizing compiler will probably make them the same. Sometimes it's nice to assign to a variable for better readability. If the container didn't contain pointers you could use a reference instead:
std::vector< Object >::iterator it;
for (it = objects.begin(); it != objects.end(); ++it)
{
const Object &o = (*it)
if(o.GetActive())
{
o.method();
o.method2();
o.method3();
//etc...
}
}
Edit: As Raymond points out in the comments, the compiler can't make certain optimizations if the methods might mutate the object in question. The way to fix that is to use const
when possible, so I've changed my example to show it in practice. If you do this you can't call methods on the object that aren't also marked const
.
Upvotes: 3
Reputation: 126787
Unless you have volatile
objects around, when dealing with local objects it mostly comes down just to readability, since compilers routinely deal with this stuff by themselves.
In your particular case, *it
is an operation that the compiler has to perform, and whose result will end in a register; so, it's almost sure that the compiler will leave the result in the register anyway for the next uses, thus "implicitly" creating your o
variable. In other words, coming down to assembly that variable arises by itself.
It's a different situation, instead, if the compiler cannot trivially prove that it
is not modified between dereferentiations (e.g. if a pointer to it - or to objects
- is passed around, or if it's nonlocal) or if it's explicitly instructed to avoid this kind of optimizations (via the volatile
keyword).
Upvotes: 0