次の仮想関数は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 にあります。
抽象クラス はインスタンス化できませんが、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;
}
}
I1
は、純粋に仮想関数(=定義のない関数)を持っているため、抽象クラスです。
抽象クラスのインスタンスを作成することはできません(どのように機能するのか?!)。したがって、I1 a
などの宣言は機能しません。
質問を編集した後は、メソッドの定義を提供したため、I1
は抽象クラスであってはならないようです。その場合は、メソッド宣言の後に= 0
を削除して、コードを機能させます。
抽象クラス(1つ以上の純粋仮想関数を持つクラス)へのインスタンスを作成することはできません。また別の問題があります。クラス宣言で関数sc.a(dir)
を呼び出すときにコンパイラーに何をさせたいですか?この線 dir = 4
も正しくありません。クラスの静的constメンバーのみをクラス宣言で初期化できます。