如何理解直接初始化和复制初始化之间的区别

时间:2017-01-28 07:15:26

标签: c++ initialization

以下内容摘自第13.1.1节。来自“C ++ Prime”,第5版:

enter image description here

为了验证上面的段落,特别是用红色下划线的语句,我写了以下代码:

#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)它不是真的。

1 个答案:

答案 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
}