#include<iostream>
#include<string>
using namespace std;
class B;
class A {
public:
A(const A&) { //copy ctor
cout << "Copy ctor A\n";
}
A() {} //default ctor
A(const B&) { //lets call this conversion ctor
cout << "B to A conversion ctor\n";
}
};
class B {
public:
};
int main()
{
B b;
A a = b;
}
以上代码打印
B to A conversion ctor
。
但根据我在环顾一段时间后发现的情况,它应该打印
B to A conversion ctor
Copy ctor A
首先,转换ctor创建类型A
的临时对象,然后将该对象复制到a
中,其中复制ctor被调用。此外,当copy ctor变为私有时,语句A a = b;
会生成此错误:
‘A::A(const A&)’ is private
显而易见,将临时对象复制到a
副本中必须是可见的。
所以我的问题是为什么复制ctor最终没有从输出中显而易见(请纠正,如果我在某处导致错误),即使它需要可访问?
答案 0 :(得分:2)
A a = b;
此表单称为copy-initialization。适用的规则规定,在这种情况下,将从A
实例构造一个临时B
对象,然后该临时用于直接初始化 a
但是,编译器允许elide副本,因为它不是必需的。即使允许省略,该类仍然需要可复制,以使表格有效。
通过将-fno-elide-constructors
传递给GCC或Clang,您可以看到没有省略的结果。
答案 1 :(得分:0)
为什么复制ctor最终没有从输出中看出来
根据标准,允许实施在某些标准中省略复制/移动构造。在这种情况下,将省略临时A
(由b
构造,并将复制到a
)的构造。
$ 12.8 / 31复制和移动类对象[class.copy]
当满足某些条件时,允许省略实现 复制/移动类对象的构造,即使构造函数 选择用于复制/移动操作和/或析构函数 对象有副作用。
和
(31.3) - 当一个临时的类对象没有绑定到一个 reference(12.2)将被复制/移动到具有相同的类对象 type(忽略cv-qualification),复制/移动操作即可 通过将临时对象直接构造到目标中而省略 省略的复制/移动