web-dev-qa-db-ja.com

C ++:フィールドを抽象型として宣言できません

次の仮想関数はI1内で純粋であるため、コンパイル時にこのエラーが発生します->フィールドM1 :: scを抽象型I1として宣言できません。助けてください。

   class I1
    {    
    public:  
        virtual void a(int dir) = 0;
        virtual void b() = 0; 
        virtual void c() = 0; 

        void a(int dir) {  
        ....
        }

        void b() {  
        ....
        }

        void c() {  
        ....
        }
    };

    class I2 : public I1
    {    
    public:  


        void a(int dir) {  
        ....
        }

        void b() {  
        ....
        }

        void c() {  
        ....
        }
    }; 

    class M1 : public G1
    {
    protected:
    I1 sc;
    public:
       int dir = 4;
       sc.a(dir);
    };

完全なコードは http://Pastebin.com/PFrMTJuF にあります。

21
user522767

抽象クラ​​ス はインスタンス化できませんが、I1のインスタンスをM1のすべてのインスタンスに埋め込むことによって、コンパイラーにそれを実行するように要求しています。

デザインを少し変更し、代わりにポインター(または、使用できる場合はスマートポインター)をI1のインスタンスに埋め込むことで、これを回避できます。

class M1 : public G1
{
protected:
    I1 *sc;
public:
    M1(I1 *sc_) {
        sc = sc_;
    }
    void foo() {
        int dir = 4;
        sc->a(dir);
    }
};

EDIT:コードを読んだ後、問題を解決する最も簡単でクリーンな方法は、現在の部屋をExecute()コマンドのメソッド、例えば何かのようなもの:

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

    virtual void Execute(Room *room) = 0;
};


class MoveCommand : public GameCommand
{
public:
    MoveCommand()
    {
    }

    void Execute(Room *room)
    {
        // Do something with `room`...
    }
};


void Game::HandleInput()
{
    // Read command from user and generate a command object from it.
    ICommand *pCommand = ParseCommand(Input::ReadCommand());
    if (pCommand) {
        pCommand->Execute(GetCurrentRoom());  // Pass current room to command.
        delete pCommand;
    }
}
17

I1は、純粋に仮想関数(=定義のない関数)を持っているため、抽象クラスです。

抽象クラスのインスタンスを作成することはできません(どのように機能するのか?!)。したがって、I1 aなどの宣言は機能しません。

質問を編集した後は、メソッドの定義を提供したため、I1は抽象クラスであってはならないようです。その場合は、メソッド宣言の後に= 0を削除して、コードを機能させます。

7
Konrad Rudolph

抽象クラス(1つ以上の純粋仮想関数を持つクラス)へのインスタンスを作成することはできません。また別の問題があります。クラス宣言で関数sc.a(dir)を呼び出すときにコンパイラーに何をさせたいですか?この線 dir = 4も正しくありません。クラスの静的constメンバーのみをクラス宣言で初期化できます。

1