2012-02-23 14 views
0

は、私はこのエラーを取得:C++未定義抽象クラスのコンストラクタ

'Undefined reference to GameState::GameState()'

しかし、私は一緒にすべてのコンストラクタを削除する場合私は上記のエラーは表示されませんが、私は仮想メソッドを呼び出すときに発生するセグメンテーションフォールトで終わる。

これは私のコードです:

#ifndef GAMESTATE_H 
#define GAMESTATE_H 

#include <stdlib.h> 

#include "Resources.h" 
#include "Renderer.h" 

class GameState { 
public: 
    GameState(); 
    virtual void init(Resources *res) = 0; 
    virtual void exit() = 0; 
    virtual void update() = 0; 
    virtual void render(Renderer *renderer) = 0; 
}; 

#endif // GAMESTATE_H 

、これはサブクラスである:

#include "GameState.h" 

class MainGameState : public GameState { 
public: 
    MainGameState() : GameState() { 

    } 

    virtual void init(Resources *res) { 

    } 

    virtual void update() { 
     printf("test\n"); 
    } 

    virtual void render(Renderer *renderer) { 

    } 

    virtual void exit() { 

    } 
private: 
    SDL_Surface *image; 
}; 
+0

そして、あなたは 'GameState :: GameState'をどこで定義しましたか? –

+0

どのようにこれらのクラスを使用していますか – rerun

+0

多分、呼び出しの例を投稿してください。また、valgrindにセグメンテーションフォールトを与えるものを尋ねることができます – Tim

答えて

2

GameState() { } 

代わりの

GameState(); 
をお試しください

または他の場所に定義してください。

仮想メソッドとは関係がありませんが、わかりません。他にバグがあると思います。おそらく、初期化されていないポインタ?

1

あなたは明示的に呼び出したい場合は、コンストラクタの実装を提供する必要があります:コンパイラは、とにかくあなたのためのパラメータのない基底クラスのコンストラクタ(デフォルトコンストラクタ)を呼び出します

class GameState { 
public: 
    GameState() {} // implementation 
    virtual void init(Resources *res) = 0; 
    virtual void exit() = 0; 
    virtual void update() = 0; 
    virtual void render(Renderer *renderer) = 0; 
}; 
+0

セミコロンを置いてはいけないと思います。 –

+0

@ MichaelKrelin-hacker right。 –

0
  1. ので、不要です。しかし、GameState::GameState()の定義を提供していますか?おそらくそうではないので、それを取り除くか実装を提供するだけです(つまり、GameState() { })。

  2. どのように関数を呼び出すのかを確認する必要があります。それは私にはうまく見えます、あなたのバグはどこかにあります。おそらく、オブジェクトへのポインタを宣言していますが、初期化しておらず、update()を呼び出していますか?私は(どうやら私は...)推測している場合は

私はあなたがこのような何かを持っていることを賭けるでしょう:

もちろん
MainGameState *state; 
state->update(); // oops! Not initialize! 

私が言ったように私は間違っているかもしれませんが、、実際のコードで質問を更新するまで推測することを余儀なくされています。

+0

@LuchianGrigore:ハハええ、私は知っている、それは精神的な瞬間でした。私はC#とC++の間を行き来するので、しばしば2つの構文を混同することがあります。コメントを投稿する前に編集しました。ありがとう。 –

+0

また、この用語は「デフォルトコンストラクタ」です。あなたはおそらく既にそれを知っていて、私はあなたが無パラメータで使用されていると推測しているので、オペレーションが理解しやすくなります。 –

+0

@LuchianGrigore:はい、わかっています。デフォルトのコンストラクタはパラメータなしです。 –

1

ここでは、探している基本クラスと派生クラスを実装する完全なプログラムがあります。 GameState::GameStateを実装したことがないため、リンカーエラーメッセージが表示されます。セグメンテーションフォルトが発生した理由は明確ではありません。

オブジェクトを多態的に削除する場合は、仮想基本クラスのデストラクタを宣言して定義することも忘れないでください。

#include <iostream> 
#define X() (std::cout << __FUNCTION__ << "\n") 
class GameState { 
public: 
    GameState() { X(); } 
    virtual ~GameState() { X(); } 
    virtual void F() = 0; 
}; 

class MainGameState : public GameState { 
public: 
    MainGameState() : GameState() { X(); } 
    void F() { X(); } 
    ~MainGameState() { X(); } 
}; 

int main() { 
    GameState* pGS = new MainGameState; 
    X(); 
    pGS->F(); 
    delete pGS; 
} 
0

このエラー'Undefined reference to GameState::GameState()'は、GameStateコンストラクタが定義されていないことを示しています。それは仮想メソッドとは関係ありません。

は@Luchianと@Michealは言った何をすべきか:スーパークラスのコンストラクタが暗黙的であることを注:

class GameState { 
public: 
    GameState() {} // implementation 

それは仮想メソッドエラーだった場合、あなたは"the 'MainGameState' must implement inherited pure virtual method 'method name'"

EDITのようなものになるだろうサブクラスをインスタンス化するときに呼び出されます。

関連する問題