Я довольно часто сталкиваюсь с этой проблемой. Скажем, у меня есть эти классы:Наследование отношения композиции в C++
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
имеют отношение «is-a» с 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
S: один из A
класса, а другой из его SuperB
класса. И переопределение desc
не так изящно.
я могу видеть, что я мог бы сеттера и добытчики на B*
в A
и переопределить их в SuperA
использовать SuperB
вместо B
, и никогда не отношусь к к B*
непосредственно и всегда использовать сорбент, но это, кажется, немного навязчивый для A
.
Пытаться составить, то есть иметь SuperA
, владеющий экземпляром A*
, также не выглядит лучше.
И еще сложнее, если A
не владеет ни одним B*
, но скажем std::vector<B*>
.
Это обычная проблема? Есть ли элегантное решение, которое я не вижу для него?
Почему вы не можете иметь защищенный c'tor в 'Ā' что принимает указатель 'B'? Затем используйте его для построения под-объекта 'A'' superA' с помощью 'superB'? – StoryTeller
Вы можете использовать 'static_cast' или' dynamic_cast', где бы вы не использовали '_superB' в' SuperA'. Не элегантный, но, возможно, достаточно для ваших целей? – anatolyg
@StoryTeller Это решение. Это немного интрузивно для A. – RedWark