你能给我最好是在组合物中使用私有继承当一个具体的例子? 就个人而言,我会用在组成私有继承,但也有可能是使用私有继承是针对特定问题的最佳解决方案的情况下。 读C ++常见问题解答 ,为您提供了使用私有继承的例子,但我似乎更容易使用成分+战略格局,甚至公有继承比私有继承。
Answer 1:
private
继承通常用来表示“实现合条件方面”。 主要采用我所看到的是使用私有多重继承,建立从各个混入父母的正确功能的子对象的混入。 这也可以用做成分(我稍微比较喜欢),但继承方法确实允许您使用using
使用混入方法时公开揭露一些父方法,并允许稍微更方便的符号。
Answer 2:
斯科特迈尔斯在“有效的C ++”项目42说
“只有继承允许访问受保护的成员,只有继承允许重新定义虚函数。因为虚函数和保护成员存在,私有继承有时来表达之间的关系,实现合条件方面唯一可行的方法类“。
Answer 3:
私人继承接口
私有继承,很多人忽视的一个典型应用如下。
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
类你感兴趣的类的各个操作的实现,你可以做成分相同,但这会丑化你的代码在你班上的其他同学。 如果你用的组合物,实施的其余部分将不得不因为复制和移动操作的此实现细节的困扰。 私有继承避免了这种和避免大量代码的重复。