C ++ - order of construction and destruction

I have the following C ++ code (VS2013):

#include <iostream>
using namespace std;
class A {
    int i;
public:
    A(int i) : i(i) {
        cout << "DEFAULT CTOR " << i << endl;
    }
    A(const A &o) : i(o.i) {
        cout << "COPY CTOR " << i << endl;
    }
    ~A() {
        cout << "DTOR " << i << endl;
    }
    friend A f(const A &, A, A *);
};
A f(const A &a, A b, A *c) {
    return *c;
}
int main() {
    f(1, A(2), &A(3));
}

      

It produces the following output:

DEFAULT CTOR 1

DEFAULT CTOR 3

DEFAULT CTOR 2

COPY CTOR 3

DTOR 2

DTOR 3

DTOR 3

DTOR 1

The first 3 are parametric constructors (erroneously outputting "DEFAULT CTOR", but it doesn't matter) that are called before being called f

.

Then, when the string is executed return *c;

, the copy constructor with the value 3 is run, followed by the destruction of the object with the value 2.

Finally, at the end of the area, the main

remaining objects (3, 3, 1) are destroyed.

I do not understand this behavior and have not found any explanation for it.

Can anyone clarify what is going on?

In particular:

  • Why is the third object &A(3)

    created before the second object A(2)

    ? Does it have anything to do with their creation (third by reference, second by value) or how it is defined f

    (second by value, third by pointer)?

  • On execution return *c;

    , a copy of the third object is created to return. Then the only object that was destroyed before returning is the second object. Again, does this have anything to do with their creation or how they are defined f

    ?

Thanks in advance.

+3


source to share


1 answer


Why is the third object & A (3) built before the second object A (2)? Does it have anything to do with creating them (third by reference, second by value) or defining the path f (second by value, third by pointer)?

This is because the order in which function arguments are evaluated is not specified by the C ++ standard. The compiler may appreciate them, but it loves. This is the reason for many instances of undefined behavior, where programmers who are unaware of it rely on a sequence that does not exist.



When return * c;, a copy of the third object is created to return. Then the only object that was destroyed before returning is the second object. Again, does this have anything to do with creating them or defining the path f?

Kind, yes. The object A(2)

is created by directly initializing the function argument f

. The scope of functional parameters is the body of the function. So it A(2)

goes out of scope when the function exits. Other objects have a slightly longer lifespan because they are created outside of the function and passed by reference / pointer. They exist until the end of the full expression f(1, A(2), &A(3));

, so they will be destroyed later.

+6


source







All Articles