g++コンパイルのundefined referenceを解決したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
garon

g++コンパイルのundefined referenceを解決したい

#1

投稿記事 by garon » 13年前

MinGWとgccの環境でOpenGL+SDLのゲームを開発しています。

複数のディレクトリで構成されているコード群のコンパイルで躓いています。
コンパイル対象のソースツリーは下のような感じになっています。
/src
 /archive
  /Archiver.h
  /ArcSave.cpp
  /ArcLoad.cpp
 /core
  /Main.cpp
  /Main.h
 /graphic
  /Texture.h
  /Texture.cpp
.
.
.
これらに対して、g++ -c /xxx/xxx.cppでコンパイルし、オブジェクトファイルから実行ファイルを生成しています。
コンパイルは全部通るのですが、実行ファイル生成する時に
Main.o:Main.cpp:(.text$_ZN4CObjC1Ev[CObj::CObj()]+0x22): undefined reference to
`vtable for CObj'
とでました。

ヘッダファイルにCObjを定義したCObject.hをMain.cppがインクルードしているのに、何故??と対策がわかりません。
何か気づくことがあったら教えて下さい。
よろしくお願いします。

box
記事: 2002
登録日時: 15年前

Re: g++コンパイルのundefined referenceを解決したい

#2

投稿記事 by box » 13年前

ソースファイル群の階層構造も大事な情報であるとは思いますが、
それよりももっと大事なのは、当該のソースファイルの中身(とりあえずMain.cppとCObject.h)であるような気がします。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: g++コンパイルのundefined referenceを解決したい

#3

投稿記事 by beatle » 13年前

externはしているが実体を定義しそこねている、とかそういう理由では?

garon

Re: g++コンパイルのundefined referenceを解決したい

#4

投稿記事 by garon » 13年前

>boxさん
すいません、大事な情報が抜けてました。
コードは次の通りです。

コード:

/*===================================================================
  object.h
===================================================================*/
#ifndef OBJECTH
#define OBJECTH

#include "Main.h"

class CObj : public CTask {
public:
  CObj() : CTask(Game->ObjList){}

	// add,delete tasklist
	void* operator new(size_t t) { return operator_new(t, Game->ObjList); }
	void operator delete(void* p) { operator_delete(p, Game->ObjList); }

	// action
	virtual bool Move();
	// display
	virtual void Draw();
};

#endif

コード:

/*===================================================================
  main.cpp
===================================================================*/
#include <stdio.h>
#include "Object.h"

CGame *Game;

// test
int main(int argc , char **argv ) {

  Game = new CGame("TEST");
  new CObj();
  delete Game;
  return 0;
}

/*===================================================================
  main.h
===================================================================*/
#ifndef MAINH
#define MAINH

#include "../system/System.h"

extern CGame *Game;

#endif

コード:


/*===================================================================
  system.h
===================================================================*/
#ifndef SYSTEMH
#define SYSTEMH

#include <SDL.h>
#include "../graphic/Texture.h"
#include "Core.h"

class CGame {
protected:
  SDL_Surface* Screen;

  void Init(const char *window_title);
public:

  // constructor
  CGame( const char *window_title );

  // destructor
  ~CGame();

  void Move();
  void Draw();
  void MainLoop();

  CTexture *Text;

  // task
  CTaskList *ObjList;

  // task system	
  void MoveTask(CTaskList* list);
  void DrawTask(CTaskList* list);

};

#endif

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: g++コンパイルのundefined referenceを解決したい

#5

投稿記事 by beatle » 13年前

CTaskの定義はどこにあるのでしょうか。
想像ですが CTask に仮想デストラクタを実装してないのではありませんか?

garon

Re: g++コンパイルのundefined referenceを解決したい

#6

投稿記事 by garon » 13年前

>beatleさん
CTaskはCore.hに記述してあり、内容は次の通りです。

コード:

/*=======================================================================
 task
=======================================================================*/
class CTask {
friend class CTaskList;
friend class CTaskIter;

	CTaskList* TaskList;

	// pointer to task list
	CTask *Prev, *Next;

	// disable new,delete not specified tasklist
	void* operator new(size_t t) {}
	void operator delete(void* p) {}
	
public:	
  // define new,delete if inherited
	static void* operator_new(size_t t, CTaskList* task_list);
	static void operator_delete(void* p, CTaskList* task_list);

	CTask(CTaskList* task_list);
	virtual ~CTask();

	// act
	virtual bool Move(){ return true; }
	// display
	virtual void Draw(){}
};

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: g++コンパイルのundefined referenceを解決したい

#7

投稿記事 by beatle » 13年前

CTask::~CTask()の実体を定義していますか?
参考 : undefined reference to vtable

garon

Re: g++コンパイルのundefined referenceを解決したい

#8

投稿記事 by garon » 13年前

はい、

コード:

~CTask() {
    // delete
    Prev->Next=Next;
    Next->Prev=Prev;
  }
と定義しています。
試しに、CObjにも何もしない仮想デストラクタを定義してみましたが、やはりダメでした。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: g++コンパイルのundefined referenceを解決したい

#9

投稿記事 by beatle » 13年前

そのデストラクタはどこに定義していますか?
No.6のソースコードにはCTaskクラスの定義の中には~CTask()の宣言しか無いので、恐らく~CTask()の定義はクラスの外側で行なっているのだと思います。
しかしそれなら

コード:

CTask::~CTask() {
    // do something
}
などと、CTask::を書く必要があると思いますがその部分は大丈夫でしょうか。

garon

Re: g++コンパイルのundefined referenceを解決したい

#10

投稿記事 by garon » 13年前

問題を自己解決できました。
原因は、コンパイル済みオブジェクトファイルのリンクミスによるものでした。
実行ファイルを生成する時に、Object.oをリンクするよう記述していなかったのが原因で、それを足したら動きました。
beatle さんが書きました:CTask::~CTask()の実体を定義していますか?
参考 : undefined reference to vtable
この参考をきっかけに、ググっている最中に似たケースを見つけ、解決に至りました。
ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る