2012-06-18 2 views
0

"추상 클래스를 인스턴스화 할 수 없습니다"나는 내가 별도의 프로젝트를 만든 다음 클래스 상속 이제다중 상속과 제 3 자 인터페이스

class Base 
{ 
public: 
    Base(); 
    virtual ~Base();  
    void SetID(unsigned short); 
    virtual inline unsigned short GetID(); 
    protected:  
    unsigned short id; 
}; 


class Generic : public Base { 
public: 
     Generic(const char *in_name); 
     const char* GetName()     { return name; } 

    protected: 
     char name[30]; 
}; 

class Actor : public Generic 
{ 
public:  
    Actor(const char *in_name); 
    ~Actor(); 
    void DoSomething(const char* str); 
}; 

와 기존 프로젝트 내가 구현할 수있는 인터페이스를 제공하고자했다가 기능을 사용하려면 - 나는 다른 구현을 위해이 프로젝트를 재사용 할 계획이다.

class MyInterface 
{ 
    public:  
     virtual ~MyInterface() {} 

     // Our methods that need to implemented 
     virtual const char* GetName() = 0;  
     virtual void DoSomething(const char* str) = 0; 
     virtual unsigned short GetID() = 0; 
}; 

이제 배우 클래스와 함께 사용하겠습니다. 클래스 배우 : 공공 일반 공개하는 MyInterface은

그러나이 문제는 아마 GetName 이미 일반에 구현되어있다

'const char *MyInterface::GetName(void)' : is abstract see declaration of  'MyInterface::GetName' 
'unsigned short MyInterface::GetID(void)' : is abstract see declaration of 'MyInterface::GetID' 
error C2385: ambiguous access of 'GetName' 
could be the 'GetName' in base 'Generic' 
or could be the 'GetName' in base 'MyInterface' 

를 컴파일하는 데 실패하고 GetID 이미 자료에서 구현 - 자식 클래스 때문에 인터페이스를 구현하는 액터는 가능하지 않습니다. 왜냐하면 컴파일러가 이미 이러한 메서드의 구현이 있다는 것을 깨닫기에 충분히 똑똑하지 않기 때문입니다.

그러나, 내가 해결 방법을 찾을 수 -하지만 이것을 위해 나는 좋은 일이 아니다 액터 클래스의 헤더를 확장해야 할 것입니다 - 그리고 난 또 다른 방법이 있는지 알고 싶어 - 내 수정

class Actor : public Generic, public MyInterface 
{ 
public:  
    Actor(const char *in_name); 
    ~Actor(); 
    void DoSomething(const char* str); 
    const char* GetName() { return Generic::GetName(); }; 
    inline unsigned short GetID() { return Base::GetID(); }; 
}; 
입니다

이제 분명히 varargs 메서드는 작동하지 않으며 기존 메서드를 구현하고 부모에게 다시 위임해야합니다. 더 나은 솔루션이 있습니까?

EDIT 기본, 일반 및 배우 클래스는 다른 사람이 관리하는 다른 프로젝트에 존재하므로 이에 대한 수정은 매우 제한적이어야합니다. - 정적 LIB를 만드는 별도의 프로젝트를 만들었습니다 - 액터 클래스와 함께 이들의 기능을 사용합니다 - 저는 자신의 프로젝트에 어떤 의존성도 가지지 않는 인터페이스를 만들었고 다른 프로젝트에 대해서도 재사용 가능한 lib를 제공합니다. 이 인터페이스를 구현해야합니다.

+1

'액터'에 두 번째 직교 인터페이스를 삽입하려는 이유를 자세히 설명 할 수 있습니까? 그것은 우리가 가능한 해결책을 개발하는 데 도움이 될 것입니다. –

+1

왜 * * MyInterface가 존재하고 다른 클래스들과의 진정한 관계가 무엇인지 설명하십시오. 그것이 그대로,이 디자인은 완전히 부서진 것처럼 보입니다. –

+0

* 컴파일러는 실현하기에 현명하지 않습니다. * ... 언어는 컴파일러가 수행 할 수있는 작업/수행해야 할 작업을 명령합니다. 이 경우 두 함수는 언어에 따라 재정의되지 않으므로 구현해야합니다. –

답변

1
class Base 
{ 
protected:  
    unsigned short id; 
public: 
    void SetID(unsigned short); 
    virtual inline unsigned short GetID() { return id; } 
    virtual ~Base() {} 
    Base(): id() {} 
}; 


class Generic 
    : public Base 
{ 
protected: 
    char name[30]; 
public: 
    const char* GetName() { return name; } 
    Generic(const char* in_name): name() {} 
}; 

class Actor 
    : public Generic 
{ 
public:  
    void DoSomething(const char* str) {} 

    ~Actor() {} 
    Actor(const char* in_name) 
     : Generic(name) 
    {} 
}; 

class MyInterface 
{ 
public:  
    // Our methods that need to implemented 
    virtual const char* name() const = 0;  
    virtual int id() const = 0; 
    virtual void doSomething(const char* str) = 0; 

    virtual ~MyInterface() {} 
}; 

template< class TpBase > 
class MyInterfaceOn 
    : public virtual MyInterface 
    , public TpBase 
{ 
public: 
    typedef TpBase Base; 

private: 
    MyInterfaceOn& mutableSelf() const 
    { return *const_cast<MyInterfaceOn*>(this); } 

public: 
    const char* name() const { return mutableSelf().Base::GetName(); } 
    int id() const { return mutableSelf().Base::GetID(); } 
    void doSomething(const char* str) { Base::DoSomething(str); } 

    MyInterfaceOn(char const name[]) 
     : Base(name) 
    {} 
}; 

class MyActor 
    : public MyInterfaceOn<Actor> 
{ 
public: 
    MyActor(char const name[]) 
     : MyInterfaceOn<Actor>(name) 
    {} 
}; 

int main() 
{ 
    MyInterface const& actor = MyActor("NN"); 
} 
+0

+1 원본 코드에 존재하는 비 const 접근 자 이외에는 레이아웃으로 문제를 해결할 수 있다고 생각합니다. –

+0

고맙지 만,이 솔루션을 읽는 한 - 저에게 관리되지 않는 전체 프로젝트 코드에서 액터 인스턴스화 및 처리가 MyActor 클래스로 대체되어야 함을 의미합니다. 원래의 솔루션은 어느 부모가 사용되어야합니까? - 나는 여기에서 향상을 보지 못합니까? – Steve

+0

@ 스티브 (Steve) : 현존하는 코드가 변경되지 않은'Actor' 클래스를 사용하고 동시에'Actor' 클래스가 어떤 식 으로든 변경되어야한다고 말하면, 그것은 단지 자기 모순입니다. 기존 액터의 인스턴스 위에 인터페이스를 제공하고 싶다면 위와 동일하게 수행하십시오. 상속하는 대신 기존 인스턴스로 전달하십시오. 설명에서 추측하기 어렵습니다. 죄송합니다. –

관련 문제