为什么删除的复制构造函数不允许使用其他具有多态类型的构造函数?
Why deleted copy constructor doesn't let to use other constructor with polymorphic type?
我想知道为什么这个程序不编译(在msvc,gcc和clang上的行为相同):
#include <iostream>
using namespace std;
struct Action
{
virtual void action()
{
cout << "Action::action()n";
}
};
struct ActionDecorator : Action
{
ActionDecorator(const ActionDecorator&) = delete;
ActionDecorator(Action & action) : origAction(action)
{
}
void action() override
{
decoration();
origAction.action();
}
private:
void decoration()
{
cout << "ActionDecorator::decoration()n";
}
Action & origAction;
};
int main()
{
Action action;
ActionDecorator actionDecorator(action);
ActionDecorator actionDecorator2(actionDecorator);
actionDecorator2.action();
}
根据我的期望,删除的复制构造函数应该让其他动作装饰器实例构造动作装饰器,因为它是多态类型的动作。相反,我必须将ActionDecorator实例显式转换为Action&,因为编译器抱怨尝试引用已删除的复制构造函数。是否有一些标准规则可以解释这种行为?
删除 a 函数不会将其从重载解析中删除。该函数仅定义为已删除。目的是在重载分辨率选择该功能时使程序格式不正确。
由于复制 c'tor比您提供的特殊基类 c'tor 更匹配,因此如果您不强制转换,重载分辨率将始终选择它。
如何最好地处理它是值得商榷的。从理论上讲,您可以让副本c'tor进行类似的包装。但是,我对拥有一个不复制的副本c'tor感到困惑。你的磨坊可能非常。
我个人更舒服的另一种选择是不按原样提供公共构造函数。相反,让客户端通过常规命名函数创建修饰器。像这样:
ActionDecorator decorate(Action& action) {
return {action};
}
现在,该类可以真正保持不可复制,并且客户端永远不需要自己转换它。如果他们将ActionDecorator
传递给decorate
,它将在构造实例之前绑定到Action
引用。所以它甚至不会考虑复制 c'tor。
但是,该类必须是可移动的,以便在C++17之前工作。
相关文章:
- 多态二进制函数
- 对象实例化调用构造函数的次数太多
- Doees the 'this' 指针参与虚函数的多态行为
- 如何在基类指针向量的元素上应用重载的多态函数
- C++:使用运算符 = 调用多参数构造函数
- 为什么删除的复制构造函数不允许使用其他具有多态类型的构造函数?
- C++ 多态构造函数错误;标识符未定义
- 多态性是否适用于值?或者在按(基)值返回时使用派生类的移动构造函数
- C 多态性实例的构造函数和破坏者
- 使用反向引用移动多态成员的构造函数
- 有没有办法破坏然后移动构造一个多态基类
- 具有引用数据类型的函数多态性
- 多态类中没有隐式复制构造函数
- 多态构造函数
- 在 C++11 中,是否可以将 ref'ed 基类传递给线程的构造函数并获得多态行为?
- C++多态性使用子构造函数
- 具有类型转换的多态复制构造函数
- 模板函数多态性
- 基类和派生类构造函数多态性问题
- 模板大小递归--构造函数多个重载