简体   繁体   中英

Why neither constructor nor assignment operator executed when declaring object?

The test program is

#include <iostream>
using namespace std;

class A
   {public:
       A (): I(0) {cout << "default construcot" << endl; };
       explicit A (int i): I(i) {cout << "another construcot" << endl; };
       A (const A& a): I(a.I) {cout << "copy constructor" << endl; }
       A& operator = (const A& a)
          {cout << "assignment operator" << endl; 
           if (this == &a) return *this; 
           I = a.I;
           return *this; 
          }
       void show () {cout << I << endl; };
    private:
       int I;
   };

int main ()
   {A a = A(1);
    A b;
    b = A(2);
    a.show();
    b.show();
    return 0;
   }

the output

another construcot
default construcot
another construcot
assignment operator
1
2

shows, that object 'a' unlike 'b' was constructed from A(1) "directly" without execution of assignment operator. But copy constructor wasn't executed too. Why? Is there a way to force execution of assignment operator in this case? I would expected such behavior if I wrote

A a (1);

but I want

A a = A(1);

which have to differs from first case. Or not?

(In fact, the problem appears when I have a class B derived from A and want A's assignment operator to handle declaration like A a = B(...).)

This

A a = A(1);

is not equivalent to this:

A a;
a = A(1);

In the second case = is an operator, in the first case = is not an operator. In the first statement it's an initialization syntax. The compiler may call copy constructor , but it can optimize it out as it's one of the places where it's allowed by the language (RVO, exception throw, etc...).

Why

The standard allows the compiler to optimize away the copy construction. Not this is NOT an assignment as it is part of the declaration (so if the optimization was not done it would result in a temporary object and then a copy construction of the temporary into a).

Is there a way to force execution of assignment operator in this case.

That will depend on your compiler. But I don not know of any that would allow you to force this (but then I have never tried turning it off). Try turning off all optimizations that your compiler is doing.

I would expected such behavior if I wrote: A a (1);

The standard explicitly states that your version can be optimized into this.

I have a class B derived from A and want A's assignment operator to handle declaration like A a = B(...).)

If you do that you will slice the B and just assign the A part of the B object.
Do you want to use a reference?

A const& a = B();

Why? Because the compiler is quite free to do so and most do.

Can you force it? No.

It's explicitly defined in the language that the compiler may remove copy constructions basically whenever it wants to, and the first form is initialization syntax anyway. However you will likely find that this behaviour is removed for when you call it with an actual derived instance as doing so would affect the correctness of your program.

I hope A a(1); and A a = 1; is strictly the same thing, it is guaranteed by standard.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM