2014-12-30 3 views
2

나는 종종이 문제에 직면한다. 이제 나는이 수업을 가정 해 봅시다 :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; 
}; 

그런 다음, 나는 새로운 정보로 AB을 확장합니다. SuperASuperB은 각각 AB과 "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의 재정의는 너무 우아하지 않습니다.

내가 AB*에 세터와 게터를 가질 수있는 볼과 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) 
    { } 
}; 

:

+0

왜 A''에서 보호 c'tor을 가질 수 없습니다 'B' 포인터를 받아들입니까? 그런 다음'superB'를 사용하여'superA'의'A' 하위 객체를 만드십시오. – StoryTeller

+0

'SuperA'에서'_superB'를 사용할 때마다'static_cast' 또는'dynamic_cast'를 사용할 수 있습니다. 우아하지는 않지만, 당신의 목적을 위해 충분한가? – anatolyg

+0

@StoryTeller 이것은 해결책입니다. A에게 약간의 방해가됩니다. – RedWark

답변

5

당신은 AB* 소요 보호 생성자가있을 수

class SuperA : public A { 
public: 
    SuperA() 
    : A(new SuperB) 
    { } 
}; 
+0

나는 그것에 대해 생각하지 않았다. 이 솔루션은 실제로 방해하지 않으며 내 질문의 후반 부분에서 내가 불러 일으킨 벡터를 지원합니다! 감사! – RedWark