2

는 :추상 기본 클래스 퍼즐

class MyData 
{ 
    int foo; 
}; 

class AbstraktA 
{ 
public: 
    virtual void A() = 0; 
}; 

class AbstraktB : public AbstraktA 
{ 
public: 
    virtual void B() = 0; 
}; 

template<class T> 
class ImplA : public AbstraktA 
{ 
public: 
    void A(){ cout << "ImplA A()"; }  
}; 

class ImplB : public ImplA<MyData>, public AbstraktB 
{ 
public: 
    void B(){ cout << "ImplB B()"; } 
}; 

void TestAbstrakt() 
{ 
    AbstraktB *b = (AbstraktB *) new ImplB; 
    b->A(); 
    b->B(); 
}; 

위의 코드의 문제는 컴파일러가 AbstraktA :: A() 정의되지 불평 것입니다.

인터페이스 A는 여러 개체에서 공유됩니다. 그러나 A의 구현은 템플릿 인수에 따라 달라집니다. 인터페이스 B는 외부 세계에서 볼 수 있으며 abstrakt가되어야합니다.

내가이하고 싶은 이유는 내가이 같은 오브젝트 C를 정의 할 수 있습니다 것입니다 : 이 템플릿 A.에 대해 다른 데이터 유형을 사용하여 C의 구현을 정의 추상의 A. 에서 상속 인터페이스 C를 정의

나는 분명히 희망한다. 이 작업을 수행 할 수있는 방법이 있습니까? 아니면 디자인을 재고해야합니까?

+0

나는 "멍청 할 수도 있지만"추상적 인 "철자가"abstrakt "일 수 있습니다. 그게 의도적 인거야? –

+1

ㅎ, 전혀 이유가 없습니다. 제 모국어로 된 결과 : –

+0

가능한 복제본 : http://stackoverflow.com/questions/254673/multiple-inheritance-from-two-derived-classes – Talvalin

답변

9

AbstracktA에서 두 가지 상속 경로가 있으며, AbstraktA :: A() 중 하나에서만 구현하므로 컴파일러가 불평합니다.

AbstraktA 기본 개체가 하나만 있도록 (AbstraktA 앞에 virtual 추가) 두 경우 모두 실제로 AbstraktA에서 상속하는 것이 좋습니다.

+0

감사합니다. 당신!! 그게 전부였다. 얼마나 쉬운 수정 :) 이전에 가상의 상속에 대해 읽었으므로 기억합니다. 그러나 실제로 사용하지 않아서 완전히 잊었습니다. 나는 좋은 방법으로 이것을 해결할 수있는 대안적인 해결책을 찾을 수 없었기 때문에 나는 내 디자인을 다시 생각해야만한다는 것을 두려워했다. 다시 한번 감사드립니다. 이것은 작동하지만, 컴파일러에서 경고로 연결 –

+0

: 는 "C4250 경고 : 'ImplB'상속 'ImplA :: ImplA :: A'지배를 통해" 에 대해 걱정이 뭔가? – Talvalin

+0

@lalithv, 그것은 당신이 원하는 것이 아닌지 염려해야 할 것이 있습니다. 이 경우 원하는 것입니다. (나는이 경고가 "매우 공통적 인 것이 아니고, 거짓보다 긍정적 인 경우가 많으며, 거짓 긍정의 경우 코드를 재구성함으로써 피할 수 없다"는 범주에 있다고 생각합니다.) – AProgrammer

0

가상 소멸자를 기본 클래스에 추가하는 것을 잊어 버렸습니다. 이것은 내가 믿는 런타임 malloc 오류로 이어진다. 디버그 모드에서

AbstraktB *b = new ImplB; 
b->A(); 
b->B(); 
delete b; 

은 삭제 문에, GCC는 나를 제공 : 의 malloc을 : *** 오류 객체 0x60e2c4을 위해 : 포인터 해제되지는

I가 기본 클래스를 변경하여이 문제를 해결

할당되지 않은 :

class AbstraktA 
{ 
public: 
    virtual ~AbstraktA(){}; 
    virtual void A() = 0; 
}; 

class AbstraktB : virtual public AbstraktA 
{ 
public: 
    virtual ~AbstraktB(){}; 
    virtual void B() = 0; 
};