【问题标题】:How to use a object whose copy constructor and copy assignment is private?如何使用复制构造函数和复制赋值为私有的对象?
【发布时间】:2010-06-05 04:57:10
【问题描述】:

在阅读TCPL时,我遇到了一个问题,正如标题所指,然后'private'类是:

class Unique_handle {
private:
    Unique_handle& operator=(const Unique_handle &rhs);
    Unique_handle(const Unique_handle &rhs);
public:
    //...
};

使用代码为:

struct Y {
    //...
    Unique_handle obj;
};

而我想执行这样的操作:

int main()
{
    Y y1;
    Y y2 = y1;
}

虽然,这些代码来自 TCPL,但我仍然无法得到解决方案...... 谁能帮帮我,不胜感激。

【问题讨论】:

  • @coanor:欢迎堆栈溢出。花几分钟时间熟悉编辑器的格式选项 - 现在我已经重新格式化您的帖子以正确显示代码
  • 嗯,为什么 Unique_handle 真的无法复制? IE。为什么没有(可复制的)唯一句柄??
  • @coanor:你想用它实现什么?创建唯一句柄然后尝试复制它以使其不再唯一有什么意义?你想做什么?

标签: c++ private-methods private-constructor


【解决方案1】:

顾名思义,Unique_handle 并不是用来复制的。它的实现通过禁用复制构造函数和复制赋值运算符来确保它。

对于可以访问Unique_handle 的多个实例的一种解决方案是持有指向它的指针,然后复制该指针。然后Y 的多个实例指向同一个唯一句柄。

注意,但是,在这种情况下要正确管理资源。

【讨论】:

  • 非常感谢,我google了我的问题,找到了构造这样一个对象的方法: static Unique_handle* instance() { return new Unique_handle(); } 但是好像不对,那我怎么在外面定义这样的对象呢?
  • @coanor:阅读有关在 C++ 中实现单例模式的信息。有很多方法 - 选择一种适合您的需求
  • 天哪,这就是我们现在的位置?如果你定义了一个私有的拷贝构造函数,并且后悔了,最好的答案是让它成为一个singleton?我为未来几年编写的代码而哭泣。
  • @jalf:虽然断章取义,但您的请求是有道理的,但我不确定在这种情况下是否有效。 OP 呈现的对象看起来确实应该是一个单例。
  • 我不明白为什么。我认为问题中没有足够的信息以任何方式将其与单身人士联系起来。他并没有说他想保证该类的实例只存在一个,也没有说它应该是全局可访问的
【解决方案2】:

您在 Stroustrup 的书中看到的示例展示了类的设计者如何明确防止复制或分配该类的对象。

该类故意使您的代码无法执行您尝试执行的操作(可能是因为该类无法正常运行或复制没有意义)。如果您希望能够复制该类的对象,则需要重新设计该类。

您可能有其他一些选项(这也可能没有意义,但这取决于您的实际操作)- 传递指向对象引用的指针而不是复制。

【讨论】:

    【解决方案3】:

    通常,将复制构造函数和赋值运算符设为私有(且未实现)的习惯用法意味着该类的原始作者明确不希望该对象是可复制的。

    【讨论】:

      【解决方案4】:

      您不应该尝试复制它。但是话虽如此......你可以memcpy它。您这样做的唯一原因是您知道自己在做什么,知道后果等等。它通常超出了通常可以接受的范围。但是你可能想做一些有点忍者的事情。

      【讨论】:

      • 正如我所说,它不推荐,但如果您确实想复制它,那么您可以....也许您出于某种奇怪的原因想在某些代理中进行热交换。
      【解决方案5】:

      我用谷歌搜索了我的问题,并找到了构造这样一个对象的方法:

      static Unique_handle* instance() { return new Unique_handle(); }

      但是好像不对,那我怎么在外面定义这样的对象呢?

      不管怎样,谢谢大家的关心。

      【讨论】:

        【解决方案6】:

        您可以使用shared_ptr 来共享对象:

        class Y
        {
        public:
          Y(): mHandle(new UniqueHandle()) {}
        
        private:
          boost::shared_ptr<UniqueHandle> mHandle;
        };
        

        就这么简单。

        如果您不想共享所有权,可以使用boost::scoped_ptr 或新创建的std::unique_ptr(如果您可以访问它),然后自己实现 CopyConstructor 和 AssignmentOperator,注意它们的语义。

        【讨论】: