我很困惑为什么这没有显示错误,因为创建了 b 的副本但没有复制构造函数 - 结构 A (行 B c{b}; )
C++是否创建了复制构造函数,还是有其他问题?谢谢
#include <iostream>
using namespace std;
struct B{
int a = 0;
B(){cout << "3" << endl;}
~B(){cout << "5" << endl;}
};
struct A{
B b;
B c{b};
A(int a){cout << "4" << endl;}
A(){cout << "1" << endl;}
~A(){cout << "2" << endl;}
};
void foo(A y){
cout << "6" << endl;
}
void foo2(A& a){
cout << "7" << endl;
}
int main()
{
B a{};
A c{};
foo(2);
foo2(c);
return 0;
}`
来自有关复制构造函数的文档
如果没有为类类型(
class
、union
或T::T(const T&)
)提供用户定义的复制构造函数,编译器将始终将复制构造函数声明为其类的非显式内联公共成员。如果满足以下所有条件,则此隐式声明的复制构造函数具有B
形式:
const B&
的每个直接和虚拟基T
都有一个复制构造函数,其参数为const volatile B&
或M
;- 类类型的
struct
1或类类型的数组的每个非静态数据成员T
都有一个复制构造函数,其参数为const volatile M&
或delete
。
也就是说,如果可以(如果每个字段都可以复制),并且您没有明确选择退出或自己编写一个,C++将为您创建一个复制构造函数。
您可以使用B
关键字选择退出复制构造函数(自 C++11 起)。
PP_3这将禁止C++创建复制构造函数,即使您没有定义复制构造函数也是如此。
在您的情况下,int
没有基类,因此第一个项目符号不适用。唯一的非静态成员是std::unique_ptr
类型,它不是类或类数组类型,因此复制起来很简单。
请务必记住,C++将生成一个复制构造函数,即使这样做在语义上不正确。例如,如果您的类包含原始指针,则C++很可能会生成一个不执行正确操作的复制构造函数。这是因为,对于原始指针,C++不理解三/五法则。
如果你的类拥有指针,你应该使用std::shared_ptr
(默认情况下它具有所有权语义,并且根据上述规则禁止复制)。如果您的类共享指针的所有权,则应使用int
,它将在存在默认复制构造函数的情况下正常工作。如果你的类借用了一个指针,你应该考虑使用引用类型,如果这不是一个选项,你应该清楚地记录你的非拥有指针,你应该考虑编写一个显式复制构造函数,如果默认的构造函数不满足三/五规则。
在您的情况下,您所拥有的只是一个(非指针)CC_19,因此不会出现更复杂的细微差别。但是如果你继续学习C++,他们会的,所以我建议在你有时间的时候仔细阅读堆栈溢出问题。