2013-02-20 6 views
3

막연한 제목을 위해 죄송합니다.기본 및 파생 클래스 생성자 다형성 문제

저는 클래스 집합을 작성 중이며 기본 생성자에서 수행 된 작업과 파생 생성자에서 수행되는 작업을 분해하는 직관적 인 방법을 생각하는 데 어려움을 겪고 있습니다.

모든 클래스는 단계 A, C, E는 순서대로 완료해야 다음과 같이

내 문제입니다. 따라서 기본 생성자에 넣는 것이 합리적입니다.

단계 B와 D는 각각의 파생 클래스에 고유합니다.

불행하게도, B는 C 이전 A 설치시 을 완료해야하며, 이와 비슷하게 D는이 OpenGL을 함수 호출입니다 E. 이전 C와 을 완료해야하고 나는 그들의 순서에 contrained하고 .

거기가 ... ++

public class MyBase 
{ 
    MyBase() 
    { 
     A(): 
     B(); 
     C(); 
     D(); 
     E(); 
    } 
    void A() {...} 
    void C() {...} 
    void E() {...} 
    virtual void B() = 0; 
    virtual void D() = 0; 
} 

public class MyDerived : public MyBase 
{ 
    MyDerived() : MyBase() {} 
    void B() {...} 
    void D() {...} 
} 

을하지만 그것은 C에 수 없습니다 :

나는 원래 기본 클래스에 가능한 한 많이 캡슐화 희망이의 라인을 따라 뭔가를 시도 다음을 제외한보다 직관적 인 방법 :

public class MyBase 
{ 
    MyBase() {} 
    void A() {...} 
    void B() {...} 
    void C() {...} 
} 

public class MyDerived : public MyBase 
{ 
    MyDerived() 
    { 
     A(): 
     B(); 
     C(); 
     D(); 
     E(); 
    } 
    void B() {...} 
    void D() {...} 
} 

최대한 많은 코드 반복을 피하기를 희망합니다.

아이디어가 있으십니까?

+1

생성자에서 이러한 메서드를 반드시 호출해야합니까? 나는 종종 post-construction이라고 불리는 "초기화"방법을 사용하는 것이 더 쉽다는 것을 발견한다. 모든 상속 된 클래스와 멤버가 기본 생성자를 가지고있는 한 그런 식으로 처리하면 아무런 장애가 없어야합니다. 모든 클래스가 공통베이스에서 파생되면 모든 벡터를 벡터에 배치하고 루프에서 initialize 메소드를 호출 할 수도 있습니다. – llakais

+0

'C'와'E'를 파생 된 타입으로 옮기는 것이 더 나을 것이라고 생각합니다. 나는이 상황을 상상하기가 힘듭니다. –

답변

0

확실히 생성자에서 호출하고 나중에 호출하는 것이 좋지 않으면 아래를 수행하여 혼란을 줄일 수 있습니다. 이제 모든 파생 클래스를 호출해야하기 때문에

public class MyBase 
{ 
    protected: 
    void templateMethod() 
    { 
     A(): 
     B(); 
     C(); 
     D(); 
     E(); 
    } 
    private: 
    void A() {...} 
    void C() {...} 
    void E() {...} 
    virtual void B() = 0; 
    virtual void D() = 0; 
}; 

public class MyDerived : public MyBase 
{ 
    MyDerived() : MyBase() {templateMethod();} 
    void B() {...} 
    void D() {...} 
}; 

이 그것이 기본 클래스에 대해 한 번 호출되는 대신,하지만 아주 진정한 템플릿 메소드 패턴이 아니다.

+1

한 가지 질문 : C++에서는 MyDerived의 ctor가 호출 될 때 vftable이 초기화된다는 보장이 있습니까? 나는 이것이 정의 된 행동이 아니므로 ctor의 가상 메소드를 호출하는 것이 위험 할 수 있다고 생각한다. –

+0

@AdrianShum :'MyDerived'의 생성자가 시작될 때,'vftable'은 이미 적절한 위치로 업데이트됩니다. –

+0

@ AdrianShum이 클래스는 파생 클래스에서 작동하도록 잘 정의되어 있지만 파생 클래스에서 파생 된 클래스는 문제를 일으킬 수 있다고 생각합니다. 비 리프 클래스가 추상이 아닌 계층에 대해서는 작동하지 않습니다. –

0

생성자에서 호출하는 가상 함수가 위험 할 수 있다고 가정하면 매크로를 사용할 수있는 솔루션을 사용하고 있습니까?

#define MY_BASE_INIT A();B();C();D();E(); 

public class MyBase 
{ 
    MyBase() {} 
    void A() {...} 
    void C() {...} 
    void E() {...} 
} 

public class MyDerived : public MyBase 
{ 
    MyDerived() 
    { 
     MY_BASE_INIT 
    } 
    void B() {...} 
    void D() {...} 
} 
+1

매크로 도움말을 호출하는 방법은 무엇입니까? MyBase는 어떻게 3 가지 방법으로 호출합니까? –

+0

사실 그것은 단순히 두 번째 솔루션입니다. 나는 일련의 메서드 호출을 매크로에 두는 것이다. 제발, 기본 클래스 –

+0

정확 하 게, 파생 클래스의 ctor에서 사용되는, 내 질문에, 어떻게 기본 생성자가 비어 있으면 직접 매크로를 호출하는 다른 호출하는 유의하십시오. 컴파일러의 관점에서 보면 동일해야합니다 –

관련 문제