web-dev-qa-db-ja.com

未定義のシンボル「vtable for ...」および「typeinfo for ...」?

ほぼ最終ステップですが、それでも奇妙なエラーがいくつかあります。

bash-3.2$ make
g++ -Wall -c -g Myworld.cc
g++ -Wall -g solvePlanningProblem.o Position.o AStarNode.o PRM.o PRMNode.o World.o SingleCircleWorld.o Myworld.o RECTANGLE.o CIRCLE.o -o solvePlanningProblem
Undefined symbols:
  "vtable for Obstacle", referenced from:
      Obstacle::Obstacle()in Myworld.o
  "typeinfo for Obstacle", referenced from:
      typeinfo for RECTANGLEin RECTANGLE.o
      typeinfo for CIRCLEin CIRCLE.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [solvePlanningProblem] Error 1

Vtableとtypeinfoの意味は何ですか?

43
Lisa

Obstacleが抽象基本クラスの場合は、そのすべての仮想メソッドを「純粋仮想」として宣言してください。

virtual void Method() = 0;

= 0は、このメソッドを派生クラスでオーバーライドする必要があり、独自の実装がない可能性があることをコンパイラに通知します。

クラスに純粋でない仮想関数が含まれている場合、コンパイラーはそれらがどこかに実装されていると想定し、その内部構造(vtableとtypeinfo)はそれらの1つと同じオブジェクトファイルに生成される可能性があります。これらの関数が実装されていない場合、内部構造が失われ、これらのエラーが発生します。

83
Mike Seymour

クラスObstacleには仮想デストラクタが必要です。デストラクタ定義を次のように変更します。

virtual ~Obstacle();

デストラクタの定義は、仮想関数を持つクラスのvtableも作成します。また、基本クラスポインターによる派生クラスインスタンスの削除が正しいことを保証します。

(質問に対する私の回答のコピー この奇妙なエラーをどうすればいいですか? 重複しているようです。)

6
janm

Obstacle.ccファイルはありますか?その場合は、それがObstacle.oに組み込まれていることを確認する必要があります。そのObstacle.oは、プログラムをリンクするときにコマンドラインに追加されます。

また、宣言するすべての非仮想メソッドを必ず定義してください。純粋な仮想デストラクタを宣言する場合は、それも定義する必要があります。

3
bk1e

このエラーが発生する別の理由があり、ここに文書化したいだけです。 RTTIのない静的ライブラリとリンクしていました。したがって、C++フラグ-fno-rtti修正済み。 RTTIが必要ない場合は、このフラグも使用できます。お役に立てれば。

1
vine'th

vtableとtypeinfoは、C++コンパイラによって生成される内部構造です。 vtableは仮想関数の呼び出しに使用され、typeinfoはRTTIに使用されます。

コンパイラによって、これらの構造を生成するときの戦略が異なります。私が見た1つの戦略は、クラスの最初の仮想関数を含む同じオブジェクトファイルにテーブルを生成することです。

1