【问题标题】:Private copy constructor with unamed argument?带有未命名参数的私有复制构造函数?
【发布时间】:2013-12-12 09:01:42
【问题描述】:

我正在从一个基本的 CPU 模拟器读取一些 C++ 代码,但我无法理解:

class CPU {
private:
    CPU (const CPU&){}
};

我理解指针,我也检查了这个:Ampersand & with const in constructor。显然它是一个(硬)复制构造函数,但我不明白,这是如何工作的?为什么是常量?为什么&符号到底没有var名称?为什么是私人的?我在我的书或 cplusplus.com 中没有找到这样的例子。

附注:

int foo(int var)  { cout << var; }
int bar(int &var) { cout << var; }

foo 和 bar 打印相同的东西? bar 本质上是在打印 *&var?

感谢任何帮助!

【问题讨论】:

    标签: c++ pointers constructor ampersand


    【解决方案1】:
    1. const 因为你没有修改你正在复制的对象
    2. & 表示引用
    3. 方法声明中不允许使用参数名称,因为只有类型很重要,名称无关紧要

    最后是私有的——这段代码只是从其他类中“隐藏”了复制构造函数,这意味着“不要复制我”。

    【讨论】:

      【解决方案2】:

      &amp; 表示在参数定义中使用时按引用传递。当您在函数范围内使用它时,这会将参数转换为指针并取消引用该指针。在您的第二个问题中,两个函数都打印相同的内容,因为 &amp; 只是说通过引用传递原始对象,而不是将其复制到函数头中。存在相同的内容,唯一的区别是一个函数复制完整的输入,另一个可以根据需要编辑源变量。

      CPU (const CPU&amp;){} 表示构造函数需要对 CPU 对象的常量引用。这意味着您只能访问 CPU 的 const 函数(并保证您不会更改原始 CPU 对象参数)。在CPU&amp; 之后没有名称仅意味着您没有将变量分配给当前范围内的名称(也就是定义后的括号将忽略该参数)。

      当构造函数是私有的时,通常意味着有另一个函数会为你生成对象。工厂通常会隐藏对象构造函数,并在为您构建对象之前需要一些其他属性/注册。

      【讨论】:

      • 那么可以使用私有复制构造函数来控制实例的数量并防止复制实例吗?有趣的。谢谢。
      【解决方案3】:

      不起作用。这里的关键词是private。整个构造的作用是创建一个只能从成员函数调用的复制构造函数,从而有效地禁用该行为。通常人们会忽略函数体,这样如果你从成员函数调用它,你也会得到一个链接错误。

      用 C++11 的说法,这将被实现为

      CPU(const CPU&) = delete;
      

      如果你真的试图诱导它:

      CPU x;
      CPU y(x); // this is the one that matches the parameters
      

      你会得到一个编译器错误,因为你不是一个成员函数,但你试图调用一个私有函数。

      他们这样做的原因是因为他们想要禁用该功能 - 您不能使用复制构造函数创建这些对象之一。

      “const CPU&”的意思是“引用一个 const CPU”。省略变量名是合法的,因为函数从不引用它,但它必须匹配参数 pattern

      【讨论】:

      • 实际上,如果其他 CPU 方法使用复制构造函数,它“可以工作”(虽然不太可能)
      • @Pyrce:这就是为什么通常不定义正文的原因。因此,如果它被意外使用,则会出现链接器错误。但这就是为什么=delete 更好,因为您不必记住不要定义它。
      • 你的意思是它不起作用?它似乎是现有项目中的代码,并且大多数 C++ 项目仍然是用 C++03 编写的最好的情况,这是对其他类隐藏复制构造函数的方法。
      • 有用的信息不知道你可以阻止这样的复制。此代码中的@IuriCovalisin main 不使用复制ctor。谢谢。
      • @ShadoWalkeR: main 不能使用 copy ctor - 这是将其设为私有的目的,如果有人试图调用它,会使编译器失败。
      【解决方案4】:

      这是一种防止您(意外)通过 e.q. 创建类实例副本的方法。将其传递给函数:

      CPU foo;
      void f1(CPU &foo) {}; f1(foo);  // work
      void f2(CPU *foo) {}; f2(&foo); // work
      void f3(CPU foo)  {}; f3(foo);  // fails
      

      因此您将无法将其粘贴到 按值调用 函数中。

      【讨论】:

        猜你喜欢
        • 2019-03-02
        • 1970-01-01
        • 2020-11-08
        • 1970-01-01
        • 2014-02-03
        • 2021-05-31
        • 1970-01-01
        • 2011-02-08
        • 1970-01-01
        相关资源
        最近更新 更多