类型t = Type()是否调用复制构造函数?

Meh*_*dad 5 c++ initialization copy-constructor visual-c++

我真的很困惑....是否Type t = Type()调用了复制构造函数或者没有?

我问,因为当我尝试:

#include <iostream>

class Test
{
public:
    Test(Test const &) { std::cout << "hello"; }
    Test() { }
};

int main()
{
    Test t = Test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

没有输出,但当我改变它

#include <iostream>

class Test
{
    Test(Test const &) { std::cout << "hello"; }
public:
    Test() { }
};

int main()
{
    Test t = Test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

error C2248: 'Test::Test' : cannot access private member declared in class 'Test'
Run Code Online (Sandbox Code Playgroud)

这没有意义(特别是因为这是一个调试版本).

更新:

即便这样编译!

struct Test
{
    Test(Test &&) = delete;
    Test(Test const &) = delete;
    Test() { }
};

int main()
{
    Test t = Test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

复制/移动构造函数是必需还是否?

Ric*_*ett 3

来自维基百科:

在 C++ 计算机编程中,复制省略是指消除不必要的对象复制的编译器优化技术。C++ 语言标准通常允许实现执行任何优化,前提是生成的程序的可观察行为与程序完全按照标准的要求执行一样(即假装)。

该标准还描述了一些可以消除复制的情况,即使这会改变程序的行为,最常见的是返回值优化。C++ 标准中描述的另一种广泛实施的优化是将类类型的临时对象复制到相同类型的对象。[1] 因此,复制初始化在性能上通常与直接初始化相当,但在语义上却不同;复制初始化仍然需要一个可访问的复制构造函数。[2] 优化不能应用于已绑定到引用的临时对象。

您正在执行复制构造,但标准允许将其转换为直接初始化,并且无论调试是否关闭,都会执行此操作,这就是未达到打印的原因。

但是,因为它“应该”是一个复制构造,所以您确实需要访问一个复制构造,这就是第二个代码不起作用的原因。