tags:

views:

310

answers:

4

Hi, this is a really simple question but I havn't done c++ properly for years and so I'm a little baffled by this. Also, it's not the easiest thing (for me at least) to look up on the internet, not for trying.

Why doesn't this use the new keyboard and how does it work?

Basically, what's going on here?

CPlayer newPlayer = CPlayer(position, attacker);
+6  A: 

This expression:

CPlayer(position, attacker)

creates a temporary object of type CPlayer using the above constructor, then:

CPlayer newPlayer =...;

The mentioned temporary object gets copied using the copy constructor to newPlayer. A better way is to write the following to avoid temporaries:

CPlayer newPlayer(position, attacker);
AraK
Brilliant, thanks.
PintSizedCat
Actually compiler will probably optimize it. In that case copy constructor will not get called.http://stackoverflow.com/questions/1758142/why-copy-constructor-is-not-called-in-this-case
BostonLogan
An assignment in a declaration isn't any less efficient than using the constructor syntax. If they had been separate statements, than the remark about temporaries would be correct. The essence is that this declares a CPlayer (typically on the stack) rather than allocating space for it from the free store (heap).
Adrian McCarthy
GCC is not calling the copy constructor, whether or not I have optimizations turned on.
jleedev
They say that in g++, you can disable this optimization with the option -fno-elide-constructors.I have not checked.
BostonLogan
If this creates an object on the stack can it live past the function it was created in's scope?
PintSizedCat
No, almost by definition: Objects on the stack only live while they are in scope. http://stackoverflow.com/search?q=%5Bc%2B%2B%5D+stack+heap
jleedev
I don't think this answer is precisely correct. The OP's code *looks* like it makes a temporary and then copies it, but the standard 12.1.11 suggests otherwise. It's just a normal constructor call, which jleedev discovered.
Kristo
It's up to the compiler whether to elide copies or not (in the situations where it's permitted). 12.8/15.
Steve Jessop
+5  A: 

The above constructs a CPlayer object on the stack, hence it doesn't need new. You only need to use new if you are trying to allocate a CPlayer object on the heap. If you're using heap allocation, the code would look like this:

CPlayer *newPlayer = new CPlayer(position, attacker);

Notice that in this case we're using a pointer to a CPlayer object that will need to be cleaned up by a matching call to delete. An object allocated on the heap will be destroyed automatically when it goes out of scope.

Actually it would have been easier and more obvious to write:

CPlayer newPlayer(position, attacker);

A lot of compilers will optimise the version you posted to the above anyway and it's clearer to read.

Timo Geusch
A: 

newPlayer is no dynamically allocated variable but an auto, stack-allocated variable:

CPlayer* newPlayer = new CPlayer(pos, attacker);

is different from

CPlayer newPlayer = CPlayer(pos, attacker);

newPlayer is allocated on the stack via the normal CPlayer(position, attacker) constructor invocation, though somewhat verbose than the usual

CPlayer newPlayer(pos, attacker);

It's basically the same as saying:

int i = int(3);
digitalarbeiter
Careful here. It's a "copy initialization". It's *not* an assignment.
sellibitze
I stand corrected, it's not an assignment; even the copy constructor isn't involved. Edit answer accordingly.
digitalarbeiter
Sure, the copy ctor is (at least logically) involved. You'll notice that if you make your copy ctor private. Then, this copy initialization won't work anymore. The C++ standard requires an accessible copy ctor even when the compiler is able to optimize out the copy.
sellibitze
+1  A: 
CPlayer newPlayer = CPlayer(position, attacker);

This line creates a new local object of type CPlayer. Despite its function-like appearance, this simply calls CPlayer's constructor. No temporaries or copying are involved. The object named newPlayer lives as long as the scope it's enclosed in. You don't use the new keyword here because C++ isn't Java.

CPlayer* newPlayer = new CPlayer(position, attacker);

This line constructs a CPlayer object on the heap and defines a pointer named newPlayer to point at it. The object lives until someone deletes it.

Kristo
"No temporaries or copying are involved" -- This is not exactly true. There is no such guarantee. But every decent compiler should elide the copy.
sellibitze