Question:
I have this code
#include <iostream>
using namespace std;
class Unit{
int a_;
char* pch_;
public:
Unit(){ cout << "Simple constr" << endl;}
Unit(int r) : a_(r), pch_(new char[100]){ cout << "Constr " << endl;}
Unit(const Unit& ){ cout << "Constr copy " << endl;}
~Unit(){
delete [] pch_;
cout << "Destr" << endl;
}
};
int main(){
Unit a = 20;
return 0;
}
Only the constructor with the parameter is called, and of course the destructor.
Why not: 1. The constructor is called with the parameter: Unit(20). 2. There is an assignment to an object that has not been created – this is copying. The copy constructor is called. Just rvalue can be passed by const T&. 3. Destructor for rvalue. 4. Destructor for a.
Answer:
In "classic" C++ (C++98), your copy-initialization is
Unit a = 20;
really conceptually meant precisely
Unit a = Unit(20);
using the conversion constructor Unit::Unit(int)
and then the copy constructor Unit::Unit(const Unit &)
. However, even in the "classic" C ++ compiler was allowed to exclude the formation of an intermediate temporary object and optimize the code to direct initialization (direct-initialization)
Unit a(20);
those. avoid calling a copy constructor even if the copy constructor had side effects. This optimization is called copy elision . (Even with copy elision, an accessible copy constructor was still required.)
Since C++17, the language has a guaranteed copy elision, in which your initialization is guaranteed to be treated as
Unit a(20);
without requiring a copy constructor.
Those. in any case, you should not (and should never) expect a mandatory call to the copy constructor here. In "classic" C++, the copy constructor could be called here, but nothing more.
In your particular case, copy-initialization behaves identically to direct-initialization, but in general, significant differences between these forms of initialization remain in C++17. for instance
struct A {
A(int) {}
};
struct B {
operator int() const { return 0; }
};
int main()
{
B b;
A a1(b); // Все в порядке
A a2 = b; // Ошибка
}
PS There is no "assignment" here, of course, at all.