简体   繁体   English

C ++不可复制类和多重继承,纯抽象类

[英]C++ non-copyable classes and multiple inheritance, pure abstract classes

We can probably agree that default copy construction is bad most of the time in C++, so it's better to disable it explicitly with either C++11 =delete or non-copyable classes like boost::noncopyable . 我们可能会同意,在大多数情况下,默认副本构造在C ++中都是很糟糕的,因此最好使用C ++ 11 =delete或不可复制的类(例如boost::noncopyable显式禁用它。

The question is, what happens in advanced scenarios when we use multiple inheritance or public abstract classes? 问题是,当我们使用多重继承或公共抽象类时,在高级方案中会发生什么?

//Class uncopyable
class uncopyable {...};

//Interface1
class IInterface1 : private uncopyable
{
public:
 IInterface1(...)
 virtual ~IInterface1(...) = 0;
};

//Interface2
class IInterface2 : private uncopyable
{
public:
 IInterface2(...)
 virtual ~IInterface2(...) = 0;
};

//Fancy implementation
//FImpl
class FImpl : public IInterface1, public IInterface2, private : uncopyable
{
public:
 FImpl(...) {...}
 ~FImpl(...) {...};
};
  • Is it a good practice to make every interface non-copyable (it seems it is, to avoid slicing)? 是否使每个接口都是不可复制的(这是避免切片的一种好习惯)?
  • Is it a good practice to add non-copyable to every derived class (explicit safeguard, but causes multiple inheritance and diamond problems?) 将不可复制的代码添加到每个派生类中是否是一种好习惯(显式保护措施,但会导致多重继承和钻石问题?)

No, it's not a good idea to make interface non-copyable. 不,使接口不可复制不是一个好主意。 For example, that prevents cloning. 例如,这可以防止克隆。

And no, it's not a good idea to derive from non-copyable in every derived class, because it's just redundant. 不,在每个派生类中从不可复制派生不是一个好主意,因为它只是多余的。

However, in order to stop especially Visual C++ from spewing out silly-warnings, it can be a good idea to declare a copy constructor and copy assignment operator in every class that should be non-copyable. 但是,为了阻止特别是Visual C ++发出愚蠢的警告,最好在每个不可复制的类中声明一个复制构造函数和一个复制赋值运算符。

A pure virtual (interface) class has no need to enforce the memory management for the use of the interface. 纯虚拟(接口)类无需为使用接口而强制执行内存管理。 Implementations of pure virtual interfaces should determine their own memory management requirements (like copy and assign). 纯虚拟接口的实现应确定其自身的内存管理要求(例如复制和分配)。

That said, value semantics allow implementations to avoid this situation entirely. 也就是说,值语义允许实现完全避免这种情况。 A value class (copyable, assignable, etc.) is easier to reason about and use. 值类(可复制,可分配等)更易于推理和使用。 All of the classes in the C++ library are value classes. C ++库中的所有类都是值类。 A good example of a value class managing memory for itself is the venerable string class. 值类自己管理内存的一个很好的例子是古老的字符串类。 Vector is also a good example. 向量也是一个很好的例子。 These classes have complex internal memory management requirements, yet, as a user of these classes, I don't have to be concerned with that aspect of the class. 这些类具有复杂的内部内存管理要求,但是,作为这些类的用户,我不必担心该类的这一方面。 I can focus on how to use the class. 我可以专注于如何使用该类。

I like this presentation from C++ Now that shows how polymorphism is also an implementation detail. 我喜欢C ++ Now的 演示 ,它展示了多态性也是一个实现细节。 This includes the ability for a client to implement classes that can participate in the polymorphism without requiring an interface class (or any base class for that matter). 这包括客户端能够实现可以参与多态性的类而无需接口类(或与此相关的任何基类)的能力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM