Question

I have the following code (I'll skip includes and what have you):

main.cpp

std::vector <actor> actors;
int main() {
    actor (2, 3);
}

actor.h

class actor
{
public:
    int x, y;
    actor(int, int);
};

actor.cpp

extern std::vector <actor> actors;
actor::actor(int x, int y)
{
    actor::x = x;
    actor::y = y;
    actors.push_back(*this);
}

Will the line:

    actor (2, 3)

actually create an instance of an actor apart from the one being pushed to the actors vector?

Note: If the code doesn't compile, ignore any mistakes. The actual code does compile, but is too convoluted to actually paste here.

Was it helpful?

Solution

Will the line:

actor (2, 3)

actually create an instance of an actor apart from the one being pushed to the actors vector?

Yes. actor(2, 3) will create a temporary object of type actor, unless it’s part of an expression that is unevaluated1. In the constructor of this temporary, a copy (of *this) will be pushed onto the stack (but note once again that in an unevaluated expression the constructor will of course not be called).

At the end of the expression which contains actor(2, 3), the temporary will be destroyed. The vector copy will remain untouched.


1 An unevaluated expression is an expression inside a sizeof(…), typeid(…), decltype(…) or noexcept(…) expression.

OTHER TIPS

It stays "alive" for the duration of the evaluation of the expression which it is a part of and is automatically disposed right after.

Example:

actor(2,3); // created and immediately destroyed
actor(2,3)->act(); // created, then acts, then destroyed
std::cout << actor(2,3) << std::endl; // created, streamed, destroyed

Gotcha (never do this)

actor const& shoot_myself(actor const& a) { return a; }
...
actor const& a = shoot_myself(actor(2,));
a->act(); // "segmentation fault / core dumped"

You forgot to place a semicolon in the end of the statement

actor (2, 3)

There must be

actor(2, 3);

A temporary object created in this line will be deleted in the same line when the control will be passed to the next statement. Its copy (the copy of the object) will be pushed by the constructor in the vector.

As the result you will have only one object of type actor that is in the vector.

You could keep the temporary object if you would define a const reference initialized by this object. For example

const actor &ar = actor( 2, 3 );

In this case you had two objects of type actor one that will be pushed in the vector and this temporary object that will be refered to by the const reference.

Here is an example that demonstrates what was said.

#include <iostream>
#include <vector>


struct A
{
    int x, y;
    A (int, int);
};

std::vector<A> v;

A::A( int x, int y ) : x( x ), y( y )
{
    v.push_back( *this );   
}

int main() 
{
    const A &ra = A( 2, 3 );

    std::cout << "ra.x = " << ra.x << ", ra.y = " << ra.y << std::endl;
    std::cout << "v[0].x = " << v[0].x << ", v[0].y = " << v[0].y << std::endl;

    return 0;
}

The output is

ra.x = 2, ra.y = 3
v[0].x = 2, v[0].y = 3

In this example the program outputs values of two different objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top