C++默认拷贝构造函数生成场景及代码拷贝无报错原因问询
关于C++默认拷贝构造函数的两个问题解答
一、C++在哪些情况下会生成默认拷贝构造函数
当类没有显式声明拷贝构造函数时,编译器会在代码需要用到拷贝构造的场景下,自动生成一个默认拷贝构造函数——这个函数会逐成员拷贝类的非静态数据成员。但存在以下几种例外,编译器不会生成默认拷贝构造函数:
- 类已经显式定义了拷贝构造函数(包括用
=delete标记为删除的版本) - 类显式声明了移动构造函数或移动赋值运算符
- 类的基类或非静态数据成员的拷贝构造函数被删除、不可访问,或者无法被调用
- (仅C03及更早标准)类显式声明了析构函数或赋值运算符(C11及之后标准已取消这一限制)
二、代码中B c{b};无报错的原因
你的代码里,struct B确实没有显式定义拷贝构造函数,但编译器自动为它生成了默认拷贝构造函数,所以B c{b};这种拷贝初始化的写法是合法的,不会报错。
默认拷贝构造函数的行为是逐成员拷贝:对于B的int a成员,直接拷贝其值;因为B没有其他复杂成员,这个默认生成的拷贝构造完全能满足需求。
另外补充一点:代码中foo(A y)函数是值传递参数,这里会调用A的默认拷贝构造函数(因为A也没有显式声明拷贝构造,也没有触发编译器不生成的例外条件),把临时构造的A对象拷贝给y。
你提供的代码
#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; }
内容的提问来源于stack exchange,提问作者Xavi
相关产品推荐
相关产品推荐

