The following is excerpted from section 13.1.1. from book "C++ Prime", 5th edition:

To verify the above paragraph, especially the statement underlined with red, I wrote the following codes:
#include<iostream>
using namespace std;
class TestClass {
public:
TestClass() :a(7) {
cout << "Default constructor";
}
TestClass(int aa) : a(aa) {
cout << "Constructor" << endl;
}
TestClass(const TestClass & t): a(t.a) {
cout << "Copy constructor" << endl;
}
TestClass & operator=(const TestClass & rhs) {
a = rhs.a;
return *this;
}
int a;
};
int main() {
TestClass t1(1);
TestClass t2 = t1;
}
Based on my understanding of the description of copy initialization in the book, the code should first create t2 using default initializer, then use operator= function to copy the right-hand operand t1. But when I debug line by line in Visual Studio 2015, the code go straight to the copy constructor TestClass(const TestClass & t). This shows that direct initialization and copy initialization are actually doing the same thing, no difference. So, is my understanding wrong or the book is wrong? If I am wrong, what is the correct understanding of the difference between direct initialization and copy initialization? Could you please give me an example code to show such difference? Thanks a lot.
Edit: someone says my question can be answered in this thread. But that thread is only a (detailed and lengthened) repeat of the text I excerpted. It doesn't answer why in practice (e.g., Visual Studio 2015) it is not true.
The book just says "copy", which doesn't just mean copy assignment. Note the word "created", copy initialization means construction, not assignment.
For TestClass t2 = t1;, t2 will be copy constructed from t1 via copy constructor directly, not default construction and then assignment.
If
Tis a class type and the cv-unqualified version of the type ofotherisTor a class derived fromT, the non-explicit constructors ofTare examined and the best match is selected by overload resolution. The constructor is then called to initialize the object.
Yes, copy initialization and direct initialization have the same effect in most cases, but there's a difference between them.
Copy-initialization is less permissive than direct-initialization: explicit constructors are not converting constructors and are not considered for copy-initialization.
e.g.
class TestClass {
public:
// the copy constructor is declared explicit now
explicit TestClass(const TestClass & t): a(t.a) {
cout << "Copy constructor" << endl;
}
TestClass(int aa) : a(aa) {
cout << "Constructor" << endl;
}
int a;
};
then
int main() {
TestClass t0(1);
TestClass t1(t0); // fine; explicit constructor works fine with direct initialization
TestClass t2 = t0; // error; explicit constructor won't be considered for copy initialization
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With