我经常面对这个问题。让我们说我有这些课程:
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
有一个&#34; is-a&#34;与A
和B
的关系。直接的方法是尝试继承:
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
:来自A
类的那个,另一个来自SuperB
类。而desc
的覆盖并不那么优雅。
我可以看到我可以在B*
的{{1}}上设置设置者和获取者,并在A
中覆盖它们以使用SuperA
代替SuperB
,永远不要直接引用B
并始终使用getter,但这似乎对B*
有点干扰。
尝试撰写,即让A
拥有SuperA
个实例也不会更好。
如果A*
不是一个A
而是一个说B*
,那就更难了。
这是一个常见问题吗?是否有一个我不明白的优雅解决方案?
答案 0 :(得分:5)
你可以让A
拥有一个受B*
保护的构造函数:
class A {
public:
A()
: _B(new B)
{ }
protected:
A(B* b)
: _B(b)
{ }
};
那样:
class SuperA : public A {
public:
SuperA()
: A(new SuperB)
{ }
};