2014-07-16 3 views
0

클래스 계층 구조를 정리하는 작업이 할당되었지만 약간의 문제가 있습니다. 쉽게 실수를 할 수있게, DerivedTwo에서클래스 계층 구조에서 변수 초기화

class Base 
{ 
Base() = 0; 

function1(); 
    ... 
function5(); 

protected: 

int variable1_; 
    ... 
int variable10_; 
}; 

class DerivedOne 
    : public Base 
{ 
    DerivedOne() = 0; 

    function6(); 
     ... 
    function10(); 

protected: 

    int variable11_; 
     ... 
    int variable20_; 
}; 

class DerivedTwo 
    : public DerivedOne 
{ 
    DerivedTwo() 
     : DerivedOne() 
    { 
     ... Fill variable1_ to variable25_ with data read from file ... 
     variable1_ = ... 
    } 

    function11(); 
     ... 
    function15(); 

    private: 

    int variable21_; 
     ... 
    int variable25_; 
}; 

그래서 25 변수가 할당되는 그 값 : 나는 지금 대략 다음과 같다 뭔가 남아 있어요. DerivedOne에서 다른 클래스를 상속 받으면 그 사람이 변수 중 하나를 초기화하는 것을 잊어 버리게됩니다.

저는이 계층 구조를 디자인하는 여러 가지 방법을 가지고 놀았지만 실제로는 아무 느낌이 없습니다.

나는이 수업이 실제로 무엇을하는지 모른 채 구체적인 것을 말하기는 어렵지만,이 디자인에 근본적인 문제가 있는지 또는 모든 변수를 초기화하는 우아한 방법을 간과했는지 알고 싶습니다. .

+0

핸들을 공유, 특정 기본이 아닌 생성자 이러한 클래스 중 하나 (예를 들어 파일 이름을 통과의 변수를 초기화하지 이유 또는 무엇이든) ? 그것을하지 않는 이유는 무엇입니까? –

+0

DerivedOne에서 상속받은 다른 클래스는 파일의 값을 초기화하지 않으므로 Base 클래스가 더 일반적이어야합니다. 미안하지만, 나는 그 말을 포스트에서 언급 했어야했다. –

+0

실제 코드를 게시 할 수 있습니까? 'Base() = 0'은 무엇입니까? 'DerivedTwo() : DerivedOne()이란 무엇입니까? 당신은'DerivedOne()'이 자동적으로 호출된다는 것을 알고 있습니까? – yngccc

답변

1

원리는 기본 오브젝트가 먼저 구축하고, 나중에 파생입니다 ... 클래스가 같은 방식으로 배치하는 이유의 문제를 해결하지 않습니다. 이를 위해서는 Base 및 DerivedOne 생성자가 자체적으로 유효한 객체를 생성해야합니다.

DerivedTwo을 구성, 코드는이 명확하게 :

DerivedTwo() 
     : DerivedOne() // First the base object constructor is called, before anything else 
    { 
     // then remaining initialisation, after DerivedOne() was created 
    } 

그래서 각 클래스는 적어도 자신의 기능 일관된 방식으로 처리 할 수있는 초기 유효한 상태로 자신의 변수를 초기화해야한다.

Base() : variable1_(/*default value here*/), variable10_(/*default value here*/) {} 
Base(int v1, int v10) : variable1_(v1), variable10_(v10) {} // for convenience 

하나의 파생 클래스가 나중에 기본 클래스의 변수를 덮어 쓸 수 있습니다. getters/setter를 사용하는 것이 더 안전하고 우아 할 것입니다.

이 디자인을 채택하면 하나의 하위 계급 클래스가 부모 중 하나의 변수를 초기화하는 것을 잊어 버리면 적어도 기본 객체가 괜찮은 방식으로 초기화되므로 파국을 초래해서는 안됩니다.

이제 파일을 읽음으로써 DerivedTwo를 시작하는 것이 문제입니다. 첫 번째 Base가 생성 된 다음 DerivedOne이 생성 된 다음 DerivedTwo 만 값을 읽는 것을 기억하십시오. 파일을 읽을 수 없거나 일관성이없는 경우 어떻게됩니까? 예외를 throw하지 않는 한 일관성이없는 객체가있을 수 있습니다.그래서 당신은이를 관리하고 DerivedTwo가 안정된 상태에 있는지 확인해야합니다 :

DerivedTwo() 
     : DerivedOne() // First the base object constructor is called 
    { 
     // then initialise all own members to a consitent state 
     // then try to read the file and manage potential errors 
    } 
+0

고마워요. 재 설계 할 때이 모든 것을 명심하겠습니다. –

0

각 클래스는 자체 데이터 멤버를 초기화해야합니다. 확인한대로 BaseDerivedX이 데이터 멤버를 초기화한다고 가정하는 것은 위험합니다. 그래서 ...

Base은 ... variable20_

DerivedTwovariable21_를 초기화해야 ... variable10_

DerivedOnevariable11_를 초기화해야한다 ... 등등 variable25_

...와 variable1_를 초기화한다 .

은 물론,이 유도에서

관련 문제