C++中组合关系的继承
Posted
技术标签:
【中文标题】C++中组合关系的继承【英文标题】:Inheritance of composition relationship in C++ 【发布时间】:2014-12-30 16:39:03 【问题描述】:我经常面对这个问题。假设我有这些课程:
class B
public:
virtual std::string className()return "B";
;
class A
public:
A()
: _B(new B)
virtual std::string className()return "A";
virtual void desc()
std::cout << "I am " << className() <<
" and I own: " << _B->className() << std::endl;
protected:
B * _B;
;
然后,我想用新信息扩展A
和B
。我确信SuperA
和SuperB
分别与A
和B
具有“is-a”关系。直接的方法是尝试继承:
class SuperB: public B
public:
virtual std::string className()return "SuperB";
class SuperA: public A
public:
SuperA()
: A()
, _superB(new SuperB)
virtual std::string className()return "SuperA";
virtual void desc()
std::cout << "I am " << className() <<
" and I own: " << _superB->className() << std::endl;
protected:
SuperB * _superB;
;
但这显然不好,因为SuperA
实际上有两个B
s:一个来自A
类,另一个来自SuperB
类。而desc
的覆盖就没那么优雅了。
我可以看到我可以在 B*
中的 A
中设置 setter 和 getter,并在 SuperA
中覆盖它们以使用 SuperB
而不是 B
,并且永远不要直接引用 B*
并且总是使用 getter,但这对于 A
来说似乎有点干扰。
尝试编写,即让 SuperA
拥有一个 A*
实例看起来也不好。
如果A
拥有的不是一个B*
而是一个std::vector<B*>
,那就更难了。
这是一个常见问题吗?有没有我看不到的优雅解决方案?
【问题讨论】:
为什么你不能在A
中有一个接受B
指针的受保护的c'tor?然后用它来构造superA
的A
子对象superB
?
您可以在SuperA
中使用_superB
的任何地方使用static_cast
或dynamic_cast
。不优雅,但可能足以满足您的目的?
@StoryTeller 这是一个解决方案。不过这对 A 来说有点麻烦。
我认为解决问题的一种方法是 A
和 SuperA
类有两个职责:它们分别将 B
或 SuperB
适配到其他接口,和 他们管理B
或SuperB
对象的生命周期。您可以通过仅提供转换 ctor A(B*)
等来拆分这些职责,然后提供另一种类型来管理这些对象的生命周期。
@RedWark,可能是这样,但恕我直言,这并不比从一开始就拥有一个受保护的成员更具侵入性。
【参考方案1】:
你可以让A
有一个受保护的构造函数,它接受B*
:
class A
public:
A()
: _B(new B)
protected:
A(B* b)
: _B(b)
;
这样:
class SuperA : public A
public:
SuperA()
: A(new SuperB)
;
【讨论】:
我没想到。这个解决方案实际上并不是那么具有侵入性,并且支持我在问题的后半部分中提到的向量!谢谢!以上是关于C++中组合关系的继承的主要内容,如果未能解决你的问题,请参考以下文章