26

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

我认为在我的风格偏好方面我并不孤单

class MyUtility : public MyBase
{
   noncopyable guard;
   ...
};

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

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

4

6 回答 6

33

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

在这里您可以阅读有关空基优化的信息。(查看“4.7:空成员优化”部分)。

编辑:事实上,不可复制没有公共构造函数,这使得它对于任何其他用途都毫无用处,而具有公共构造函数的类也可以用于其他错误目的。这是另一个原因,为什么 boost 选择了这种方法。

于 2011-01-28T15:12:29.427 回答
23

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

于 2011-01-28T15:29:14.460 回答
4

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

于 2011-01-28T16:05:09.950 回答
4

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

于 2011-01-28T16:42:11.923 回答
0

如果省略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 {};
于 2011-02-01T17:53:10.540 回答
0

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

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;
};

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

于 2019-05-26T21:44:47.717 回答