【问题标题】:why does boost::noncopyable require inheritance为什么 boost::noncopyable 需要继承
【发布时间】:2011-06-17 07:30:57
【问题描述】:

将任何不可复制的成员添加到类将阻止自动生成复制构造和赋值运算符。为什么 boost 需要继承才能使用不可复制?

我认为我对

的风格偏好并不孤单
class MyUtility : public MyBase
{
   noncopyable guard;
   ...
};

相对于

class MyUtility : public MyBase , private noncopyable
{
   ...
};

Dave Abrahams 是个聪明人,所以他可能考虑过这种可能性。我错过了什么?继承有什么作用?

【问题讨论】:

    标签: c++ boost noncopyable


    【解决方案1】:

    因为sizeof(boost::noncopyable)!=0。所以在这种情况下,你的班级规模会更大。

    Here 你可以阅读空基优化。 (查看“4.7:空成员优化”部分)。

    编辑:事实上,noncopyable 没有公共构造函数使得它无法用于任何其他用途,而具有公共构造函数的类也可能用于其他错误目的。这是 boost 选择这种方法的另一个原因。

    【讨论】:

    • 对于那些不理解答案的人来说,允许编译器强制引用“空基优化”:)
    • 我接受这个作为答案,但它也应该提到一个事实,即 boost 的方法阻止子类化以显式提供复制功能。
    • @Mark Borgerding 我不明白你到底想在我的答案中添加什么。我编辑了它。如果您想添加其他内容,请告诉我。
    【解决方案2】:

    如果您可以使用noncopyable 作为成员,则需要一个公共的默认构造函数和析构函数。然后人们可以创建noncopyable 的实例,甚至可以将其用作多态基类,而没有析构函数是虚拟的。没有任何公共成员的实现只是确保它仅用作策略类。

    【讨论】:

      【解决方案3】:

      就个人而言,我更喜欢 boost 语法。继承是为整个类添加一些属性或特性的一种方式,不可复制就是这样的特性。不可复制成员似乎很棘手(您实际上不想添加任何成员,这是一个技巧)。继承正好用于它的设计目的。

      【讨论】:

        【解决方案4】:

        最明显的原因是派生类“isA”不可复制,因此使用继承最有意义。以这种方式使用它并不会增加类的大小这一事实今天也是一个考虑因素(但我认为不可复制在空基类优化之前)。

        【讨论】:

        • 编译器何时布局派生类对象,就好像基子对象是成员子对象一样?在我看来,基础子对象尾部填充的重用已经存在了几十年(至少一个)。
        【解决方案5】:

        如果您省略 private 名称,它几乎就像英语:

        // English: this is my car, it is not copyable
        class MyCar: noncopyable {};
        
        // my truck is noncopyable, did i mention it's also a vehicle?
        class MyTruck: noncopyable, public MyVehicle {};
        
        // My airplane is a vehicle, BTW it's not copyable
        class MyAirplane: public MyVehicle, noncopyable {};
        

        【讨论】:

          【解决方案6】:

          我自己也遇到过这个设计决定,我认为将其作为成员的额外自我文档实际上是值得的。例如,有人可能会质疑“为什么类不可复制?”。

          class VertexBuffer
          {
             std::sr1::noncopyable<GLint> m_vbo;
             ...
          };
          

          这现在明确告诉我该类是不可复制的,因为如果 OpenGL VBO 被释放两次,这将是一个错误。

          例如,在前面的例子中;我可以模仿狗,为什么你的车这么特别,我不能模仿?

          我将它与 zeroinitialized / valueinitialized 之类的东西再次结合起来,以获得额外的文档,我不需要确保在使用它们之前已经分配了这些变量。

          class VertexBuffer
          {
             std::sr1::noncopyable<GLint> m_vbo;
             std::sr1::zeroinitialized<int> m_vertexCount;
          };
          

          我参加这个聚会有点晚了,但有人有更多建议吗?

          【讨论】:

            猜你喜欢
            • 2012-03-05
            • 2016-08-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-26
            • 2010-12-07
            • 1970-01-01
            相关资源
            最近更新 更多