以下内容摘自第13.1.1节。来自“C ++ Prime”,第5版:
为了验证上面的段落,特别是用红色下划线的语句,我写了以下代码:
#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;
}
根据我对本书中复制初始化描述的理解,代码应首先使用默认初始值设定项创建t2
,然后使用operator=
函数复制右侧操作数{{1} }。但是当我在Visual Studio 2015中逐行调试时,代码直接转到复制构造函数t1
。这表明直接初始化和复制初始化实际上是做同样的事情,没有区别。那么,我的理解错了还是这本书错了?如果我错了,正确理解直接初始化和复制初始化之间的区别是什么?你能给我一个示例代码来展示这种差异吗?非常感谢。
编辑:有人说我的问题可以在this thread中回答。但是那个帖子只是我摘录的文本的重复(详细和延长)。它没有回答为什么在实践中(例如,Visual Studio 2015)它不是真的。
答案 0 :(得分:1)
这本书只是说&#34; copy&#34;,这并不仅仅意味着复制任务。注意单词&#34; created&#34;,copy initialization表示构造,而不是赋值。
对于TestClass t2 = t1;
,t2
将通过复制构造函数直接从t1
复制构建,而不是默认构造,然后分配。
如果
T
是类类型且other
类型的cv-nonqualified版本是T
或从T
派生的类,则非显式构造函数检查T
,并通过重载决策选择最佳匹配。然后调用构造函数来初始化对象。
是的,复制初始化和直接初始化在大多数情况下具有相同的效果,但它们之间存在差异。
复制初始化比直接初始化更不宽容:显式构造函数不转换构造函数,不考虑复制初始化。
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;
};
然后
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
}