当前位置: 首页 > 知识库问答 >
问题:

为什么删除的拷贝构造函数不允许使用其他具有多态类型的构造函数?

商飞翮
2023-03-14

我想知道为什么这个程序不编译(在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实例构造ActionDecorator,因为它是多态类型的操作。相反,我必须显式地将ActionDecorator实例转换为Action

共有1个答案

司马祖鹤
2023-03-14

删除函数不会将其从重载解析中删除。该函数仅定义为已删除。目的是在重载解析选择该函数时使程序格式错误。

因为复制c'tor比您提供的特殊基类c'tor更匹配,所以如果您不强制转换,重载解析将始终选择它。

如何最好地处理它是有争议的。理论上你可以让复制者做类似的包装。然而,我为有一份不抄袭的抄本而苦恼。你的百万美元可能很贵。

另一个选择是不提供公共构造函数,我个人对此更为满意。相反,让客户机通过常规命名函数创建装饰器。大概是这样的:

ActionDecorator decorate(Action& action) {
  return {action};
}

现在,该类可以真正保持不可复制,客户机将永远不需要自己铸造它。如果他们将ActionDecorator传递给decoration,则在构建实例之前,它将绑定到Action引用。所以它甚至不考虑拷贝。

然而,为了在C17之前工作,该类必须是可移动的。

 类似资料:
  • 主要内容:默认拷贝构造函数拷贝和复制是一个意思,对应的英文单词都是 。 对于计算机来说,拷贝是指用一份原有的、已经存在的数据创建出一份新的数据,最终的结果是多了一份相同的数据。例如,将 Word 文档拷贝到U盘去复印店打印,将 D 盘的图片拷贝到桌面以方便浏览,将重要的文件上传到百度网盘以防止丢失等,都是「创建一份新数据」的意思。 在 C++ 中,拷贝并没有脱离它本来的含义,只是将这个含义进行了“特化”,是指用已经存在的对

  • C++ 类 & 对象 拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给函数。 复制对象,并从函数返回这个对象。 如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最

  • 本文向大家介绍详解C++ 拷贝构造函数,包括了详解C++ 拷贝构造函数的使用技巧和注意事项,需要的朋友参考一下 拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给函数。 复制对象,并从函数返回这个对象。 如果在类中没有定义拷贝构造函数,编译器会自行定

  • 我正在使用一种通信标准(我无法控制),该标准定义要在各种数据包中发送/接收的数据项。 每个项目都由自定义类型和类型相关信息定义。这些项目很少会改变。我希望能够将项目构造函数的范围限制在一个地方,并将那里的所有项目定义为(类似于枚举)。 目前,我有一个用于类型的枚举和一个用于项的类。 这已经变得难以管理,我正在寻找更好的模式/结构。 我可以有一个抽象的Item类,以及每种类型的子类。使用此设置,我不

  • 我总是得到与此类似的结果。为什么第一个电话比其他电话要花10倍的时间?

  • 问题内容: 这些来自github上的spring amqp示例,位于https://github.com/SpringSource/spring-amqp- samples.git 这些是 什么类型的Java构造函数?它们是吸气剂和吸气剂的捷径吗? 与此相反 问题答案: 这些构造函数被重载以使用调用另一个构造函数。第一个无参数构造函数使用空参数调用第二个。第二呼叫的第三构造(未示出),其必须采取,