2011-07-06 11 views
0
struct A { 
    B b; 
    A(int x):b(x){} 
    A(int x, float g) // how to implement this? I want to init b as a C. 
}; 
struct B { 
    enum {e_c, e_d} type; 
    int i; 
    B(int i_):i(i_){} 
}; 
struct C : public B { 
    float f; 
    C(int i_, float f_):B(i),f(f_){} 
}; 
struct D : public B { 
    double ff; 
    D(int i_, double d):B(i),ff(d){} 
}; 

아마도 이것을 코딩하는 다른 방법이 있을까요? 원래 B 클래스가 있었지만 B 필드에 계속해서 (호환되지 않는/상호 배타적 인) 필드를 추가하지 않기로 결정했습니다. A 솔루션을 사용하면 b 열거 형을 검사하여 어떤 유형인지 확인합니다. 그런 다음 B *를 C * 또는 D *에 캐스트하여 부동 소수점 또는 이중을 얻습니다. 내 문제는 이제 내가 A를 초기화시키는 방법을 모른다. 그 언어가 내가 그런 것을 할 수있게 해주는가?하위 클래스의 ctor로 초기화

편집 : 방금 A 's b가 C 또는 D의 추가 입력란을 허용 할 공간을 할당하지 못했다는 사실을 깨달았습니다. float 또는 double을 저장할 수있는 공간이 없습니다. 그래서 내가 원하는 것을하기위한 올바른 방법은 B에 union {float f; double ff;};을 추가하는 것입니다.

+0

"B"형의 실제 객체 멤버가 있으므로 "b"를'C'로 초기화 할 수 없습니다! ** ** 객체를'B *'로 만들 수는 있지만,'C '형의 멤버를 직접 만들지는 않겠습니까? –

+0

어쨌든 가능한 파생 된 클래스를 열거하는 기본 클래스의 열거 형을 가지고 다가오는 디자인 자동차 충돌과 같은 냄새가 난다. 실제 문제를 게시하면 더 나은 해결책을 생각할 수 있습니다. –

+0

나는 문법에 또 다른 방법을 추측한다. 나의 질문은 : 노조를하기위한 더 많은 OOP 방법이 있는가? 난 단지 내가이 예 에서처럼 float과 double을 가지고 있고, double 값을 float 값으로 해석하고, 쓰레기를 얻고, 더러운 버그. –

답변

2

예제가 약간 혼란 스럽습니다. 하지만 포인터를 원하니? 이 작업을 수행 할 경우, 해야B가 가상 소멸자를 가지고

struct A { 
    B *b; 
    A(int x):b(new B(x)) {} 
    A(int x, float g):b(new C(x,g)) {} 
    ~A() { delete b; } // Very important! 
}; 

참고. A 오브젝트를 복사하는 것이 무엇을 의미하는지 생각할 필요가 있습니다.

+0

**'B' 가상 소멸자에게 ** 언급해야합니다! :-) 그리고 당신이 그것에있는 동안'A'를 복사 할 수 없게하십시오. 또한 열거 형을'B'에 넣으려는 OP의 아이디어는 곧 나올 나쁜 디자인 선택처럼 보일 것입니다. –

+0

@Kerrek : 아, 좋은 지적은 가상 dtor가 OP의 코드에서 누락 된 것을 발견하지 못했습니다. 복사/할당은 접선의 정원 경로를 쉽게 이끌 수 있지만, 나는 또한 언급 할 것이다. –

1

수정 사항이 정확합니다.

아마 당신이 원하는 것을하기위한 정상적인 방법은 B을 (바람직하게는 스마트 한) 포인터로 저장하고 적절한 생성자를 해당 생성자에 할당하는 것입니다.

관련 문제