[英]Inheritance of composition relationship in C++
I quite often confront myself to this problem. 我经常面对这个问题。 Let's say I have these classes: 假设我有以下课程:
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;
};
Then, I want to extend A
and B
with new information. 然后,我想用新信息扩展A
和B
I am sure that SuperA
and SuperB
have a "is-a" relationship with A
and B
, respectively. 我确信SuperA
和SuperB
分别与A
和B
具有“ is-a”关系。 The straightforward way would be to do try inheritance: 直接的方法是尝试继承:
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;
};
But this is obviously not good, since SuperA
would have actually two B
s: the one from the A
class, and the other from its SuperB
class. 但这显然不好,因为SuperA
实际上有两个B
:一个来自A
类,另一个来自其SuperB
类。 And the override of desc
is not so elegant. 而且desc
的覆盖不是那么优雅。
I can see that I could have setters and getters on B*
in A
and override them in SuperA
to use a SuperB
instead of a B
, and never refer to to B*
directly and always use the getter, but this seems a bit intrusive for A
. 我可以看到我可以在A
B*
上使用setter和getter,并在SuperA
覆盖它们以使用SuperB
而不是B
,并且从不直接引用B*
并始终使用getter,但这似乎有点干扰A
Trying to compose, ie having SuperA
owning an A*
instance does not look better either. 尝试SuperA
,即让SuperA
拥有一个A*
实例看起来也不好。
And it gets even harder if A
owns not a single B*
but a say std::vector<B*>
. 如果A
不拥有单个B*
而是说std::vector<B*>
,那就变得更加困难。
Is this a common problem? 这是个常见的问题吗? Is there an elegant solution that I don't see for it? 有没有我看不到的优雅解决方案?
You could just have A
have a protected constructor that takes a B*
: 您可能只让A
具有一个受保护的构造函数,该构造函数采用B*
:
class A {
public:
A()
: _B(new B)
{ }
protected:
A(B* b)
: _B(b)
{ }
};
So that: 以便:
class SuperA : public A {
public:
SuperA()
: A(new SuperB)
{ }
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.