您能给我举一个明确的例子,说明何时使用私有继承比组合更好?个人而言,我会优先选择组合而非私有继承,但在某些情况下,使用私有继承可能是解决特定问题的最佳方案。阅读C++ faq可以给出使用私有继承的例子,但似乎使用组合+策略模式或者甚至公共继承都比私有继承更加容易。
您能给我举一个明确的例子,说明何时使用私有继承比组合更好?个人而言,我会优先选择组合而非私有继承,但在某些情况下,使用私有继承可能是解决特定问题的最佳方案。阅读C++ faq可以给出使用私有继承的例子,但似乎使用组合+策略模式或者甚至公共继承都比私有继承更加容易。
Scott Meyers在《Effective C++》第42条中说:
"只有继承才能访问受保护的成员,也只有继承才允许重定义虚函数。由于虚函数和受保护的成员存在,所以私有继承有时是表达类之间实现关系的唯一实用方法。"
private
继承通常用于表示“基于实现”。我看到的主要用途是使用私有多重继承的mixin来构建具有来自各种mixin父类的适当功能的子对象。这也可以使用组合(我稍微更喜欢)完成,但继承方法允许您使用using
公开一些父方法,并在使用mixin方法时允许稍微更方便的符号。
许多人忽视的私有继承的典型应用是以下情况。
在IT技术中,私有继承可以用于隐藏实现细节并限制对基类接口的公共访问。这样,派生类只能通过调用基类的公共成员函数来访问其接口。
class InterfaceForComponent
{
public:
virtual ~InterfaceForComponent() {}
virtual doSomething() = 0;
};
class Component
{
public:
Component( InterfaceForComponent * bigOne ) : bigOne(bigOne) {}
/* ... more functions ... */
private:
InterfaceForComponent * bigOne;
};
class BigOne : private InterfaceForComponent
{
public:
BigOne() : component(this) {}
/* ... more functions ... */
private:
// implementation of InterfaceForComponent
virtual doSomething();
Component component;
};
BigOne
是一个承担许多职责的类。为了将代码模块化,您需要将代码分解为组件,这些组件可以帮助处理一些小事情。这些组件不应该是 BigOne
的朋友,但它们仍然可能需要访问你不想公开的类的某些内容,因为这些是实现细节。因此,您需要为此组件创建一个接口来提供受限制的访问。这使得您的代码更易于维护和理解,因为事物有明确的访问边界。struct
或class
中,并进行私有继承。struct MyClassImpl
{
int i;
float f;
double d;
char c;
std::string s;
// lots of data members which can be copied/moved by the
// compiler-generated constructors and assignment operators.
};
class MyClass : private MyClassImpl
{
public:
MyClass( const MyClass & other ) : MyClassImpl( other )
{
initData()
}
MyClass( MyClass && other ) : MyClassImpl( std::move(other) )
{
initData()
}
// and so forth ...
private:
int * pi;
void initData()
{
pi = &p;
}
};
您可以使用MyClassImpl
类的编译器生成操作来实现您感兴趣的类的各自操作。您也可以通过组合方式实现,但这会使您的代码在类的其他部分变得混乱。如果您使用组合,则由于复制和移动操作的实现细节,整个实现将受到影响。私有继承可避免此问题,并避免大量的代码重复。
~InterfaceForChild()
有什么用?为什么前面要加上~
?客户端初始化和调用哪个类? - InsaneBot~InterfaceForComponent
。 - Aidiakapi