C++自动生成的具有常量和非常量引用的复制构造函数

C++ auto-generated copy constructors with const and non-const refs

本文关键字:常量 引用 复制 构造函数 非常 C++ 自动生成      更新时间:2023-10-16

请考虑以下代码片段:

#include <iostream>
struct Foo {
Foo() = default;
Foo(Foo &) {
std::cout << "Foo(Foo &)" << std::endl;
}
};
struct Bar { Foo m; };
int main() {
Bar b;
Bar b2(b);
}

如果运行此代码,则写入Foo(Foo &(消息。好的,由于Foo没有Foo(const Foo &)构造函数,因此Base(Base &)构造函数是为Base生成的。现在,如果我们在Foo的定义中添加以下内容:

Foo(const Foo &) {
std::cout << "Foo(const Foo &)" << std::endl;
}

将写入 Foo(const Foo &(消息。好的,现在Foo有带有const ref参数的复制构造函数,所以Base(const Base &(是由编译器生成的。但是,如果我声明Foo(const Foo &)明确删除:

Foo(const Foo&) = delete;

然后程序将不会编译并出现以下错误:

prog.cc: In function 'int main()':
prog.cc:15:13: error: use of deleted function 'Bar::Bar(const Bar&)'
Bar b2(b);
^
prog.cc:11:8: note: 'Bar::Bar(const Bar&)' is implicitly deleted because the default definition would be ill-formed:
struct Bar { Foo m; };
^~~
prog.cc:11:8: error: use of deleted function 'Foo::Foo(const Foo&)'
prog.cc:8:5: note: declared here
Foo(const Foo&) = delete;
^~~

在代码的第一个修订版中,如果没有生成Foo(const Foo&),为什么我们没有错误,就像在第三次修订版中一样?如果它已生成,为什么不像在第二次修订版中那样调用它(不产生输出消息(?

如果没有用户声明的复制 ctor、move-ctor 或 move-assignment-运算符,则隐式声明和定义复制构造函数。

它的形式X(const X&)如果所有虚拟碱基、直接碱基和非静态数据成员T声明一个接受const T&的复制 ctor。
否则,它的形式是X(X&).

隐式声明的复制 ctor 是默认的,如果默认定义(成员级复制(格式不正确,则会删除默认的复制 ctor。

您收到一个错误,因为子对象 copy-ctor 接受 const&被删除,导致包含类 copy-ctor 被删除。

如果您将其添加到代码中

Foo(const Foo&) = delete;

并试图打电话

Bar b2(b);

你用Foo(const Foo&) = delete;编码

#include <iostream>
struct Foo {
Foo() = default;
Foo(const Foo&) = delete;
Foo(Foo &) {
std::cout << "Foo(Foo &)" << std::endl;
}
};
struct Bar { Foo m; };
int main() {
Bar b;
Bar b2(b);
}

您正在尝试调用隐式删除的 Bar 复制构造函数