0

次のクラス継承を持つ既存のプロジェクトがあります

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;
};

今、私は単にこれを私のアクタークラスで使用したかったのです。例えば、クラス Actor : public Generic、public MyInterface

ただし、コンパイルに失敗します

'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'

問題はおそらく、GetName が既に Generic に実装されており、GetID が既に Base に実装されていることです。そのため、子クラスで Actor を実装することはできません。これは、コンパイラがこれらのメソッドの実装が既に存在することを認識できるほど賢くないためです。

ただし、回避策を見つけました-しかし、これにはアクタークラスのヘッダーを拡張する必要がありますが、これは良いことではありません-別のアプローチがあるかどうかを知りたかった-私の修正は

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 メソッドでは機能せず、既存のメソッドを実装して親に再度委任する必要があります-より良い解決策はありますか?

編集明確にするために-クラスbase、generic、およびactorは、他の人が管理する別のプロジェクトに存在します。これらへの変更は非常に制限する必要があります。- 静的 LIB を作成する別のプロジェクトを作成しました - これらの関数をアクター クラスと組み合わせて使用​​するために - 自分のプロジェクトに依存しないようにインターフェイスを作成し、他のプロジェクトに再利用可能なライブラリを提供します。このインターフェースを実装する必要があります。

4

1 に答える 1

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" );
}
于 2012-06-19T01:12:32.863 に答える