나는 종종이 문제에 직면한다. 이제 나는이 수업을 가정 해 봅시다 :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
은 각각 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
들 것 때문에 이것은 분명히 좋지 않아 다음 A
클래스의 하나, 그 SuperB
클래스에서 다른. 그리고 desc
의 재정의는 너무 우아하지 않습니다.
내가 A
에 B*
에 세터와 게터를 가질 수있는 볼과 B
대신 SuperB
를 사용하는 SuperA
에서 그들을 무시하고, 결코 항상 직접 B*
를 참조하지 않으며 게터를 사용하지만,이 조금 보인다 수 있습니다 A
에 관여합니다.
A*
인스턴스가있는 SuperA
을 작성하려고 시도하는 것이 좋지 않습니다.
A
이 하나의 B*
은 아니지만 std::vector<B*>
을 소유하는 경우 더 어려워집니다.
일반적인 문제입니까? 거기에 내가 볼 수없는 우아한 솔루션이 있습니까? 그래서
class A {
public:
A()
: _B(new B)
{ }
protected:
A(B* b)
: _B(b)
{ }
};
:
왜 A''에서 보호 c'tor을 가질 수 없습니다 'B' 포인터를 받아들입니까? 그런 다음'superB'를 사용하여'superA'의'A' 하위 객체를 만드십시오. – StoryTeller
'SuperA'에서'_superB'를 사용할 때마다'static_cast' 또는'dynamic_cast'를 사용할 수 있습니다. 우아하지는 않지만, 당신의 목적을 위해 충분한가? – anatolyg
@StoryTeller 이것은 해결책입니다. A에게 약간의 방해가됩니다. – RedWark