2017-06-22 22 views
-3

私は多くの答えを検索しましたが、私の問題を解決することはできません。私はC++を初めて使っています。以下は私のコードの簡略化された抽出です。C++ undefined vtable例外への参照

TestHeader.h:

#ifndef NAMESPACE_TESTHEADER_H_ 
#define NAMESPACE_TESTHEADER__H_ 

namespace Namespace { 

class TestHeader { 

    public: 

    TestHeader(const std::string& str) : anyString_(str) { } 

    virtual std::string methodOne(const std::string& param) const; 

    virtual ~TestHeader() { anyString_.clear(); } 

    protected: 
     std::string anyString_; 
}; 
} 

#endif //NAMESPACE_TESTHEADER__H_ 

TestHeader.cpp:

#include "TestHeader.h" 

using namespace std; 

namespace Namespace { 

TestHeader::TestHeader(const std::string& str):anyString_(str) { <do something>; } 

std::string TestHeader::methodOne(const std::string& param) const 
{ 
    return <A string>; 
} 

TestHeader::~TestHeader() { 
    anyString_.clear(); 
} 
} 

私は単に私のパッケージ内の他の.cppファイルに次の行を呼び出した何をしたか:

#include "TestHeader.h" 
TestHeader testHeader("whatever"); 

ビルドは投げに失敗した

error: undefined reference to 'vtable for Namespace::TestHeader' 
the vtable symbol may be undefined because the class is missing its key function 

最も奇妙なことは、次のとおりです。ヘッダーのみで一緒にデストラクタで、私は、ヘッダーと.CPPでの実装でvirtual std::string methodOne(const std::string& str) const;をコメントアウトする場合は、OR、私は、コンストラクタの後: anyString_(str)をコメントアウトした場合とanyString_.clear();、ビルドが成功します。

+1

コンストラクタとデストラクタを2回定義したのはなぜですか?それはコンパイルするべきではありません。あなたがソースを適切にコンパイルしてリンクしていないと思います。 – Curious

+0

コンストラクタとデストラクタの再定義をコンパイルしないと思います。 – user1438832

+2

ヘッダに 'std :: string'を含めないでください。失敗はリンケージ上にあるだけではありません。適切な[mcve]を投稿してください。何も複製していない、ダムダウンしたものではありません。 – StoryTeller

答えて

0

最初に、ヘッダーファイルの先頭に#include <string>を含めます。コンパイル後に生成されたオブジェクトファイルをリンクしていないためです。testHeaderという名前の宣言と初期化が含まれているソースファイルにリンクされていません。

これらをコンパイルするには、それはあなたがコンストラクタの複数の定義を持っていることを言って文句を言い

g++ -std=c++14 TestHeader.cpp yourfile.cpp 

あなたがこれらのエラーを参照した後、複数の定義を削除し、いずれかのcppファイル内のすべてのあなたの定義を置くか、一つだけの場所でそれらを配置し、再コンパイルとリンク上記のコマンドを使用します。リンカーのエラーはなくなるはずです。

1

第1回コンストラクタとデストラクタを2回定義しないでください。コメントで奇妙に述べたようにコンパイルするべきではありません

第2に、仮想関数の基本的な使用であるランタイム多態性が実装されていないので、クラスを抽象化したくないと思います。

あなたはクラスTestHeaderが.C++コンパイラは仮想関数を持つクラスから継承した仮想関数やクラスを持つすべてのクラスの仮想表を挿入Virtual Tableを参照しているvirtualキーワードを削除抽象的にしたくない場合。

Virtualキーワードの使用をよく調べて、コードを書いてください。ここで が同じ Link 1 Link 2

のクイックリンクです。また、私はあなたがどんな意味がありませんvirtual ~TestHeader() { anyString_.clear(); }デストラクタからいくつかの概念を再検討する必要があると思います。実際には、の場合に使用されるVirtual Destructorの使用を拒否する基本クラスはありません