2012-02-23 10 views
25

ファイルああと継承

#ifndef A_H_ 
#define A_H_ 

class A { 
public: 
    virtual ~A(); 
    virtual void doWork(); 
}; 

#endif 

ファイルChild.h

#ifndef CHILD_H_ 
#define CHILD_H_ 

#include "A.h" 

class Child: public A { 
private: 
    int x,y; 
public: 
    Child(); 
    ~Child(); 
    void doWork(); 
}; 
#endif 

そしてChild.cpp

#include "Child.h" 

Child::Child(){ 
    x = 5; 
} 

Child::~Child(){...} 

void Child::doWork(){...}; 

コンパイラは、未定義の参照があることを述べていますAのvtableに変更します。 私はいろいろなことを試みましたが、まだ誰も働いていません。

私の目的は、クラスAがインターフェイスであり、ヘッダーから実装コードを分離することです。

+4

宣言したすべての非純粋仮想関数を定義する必要があります。宣言しても使用しない非仮想関数を定義する必要はありません。 –

答えて

60

なぜエラー&どうすれば解決できますか?

あなたはclass A内のすべての仮想関数についてdefinitionsを提供する必要があります。純粋仮想関数のみが定義を持たないことが許されます。

すなわち:class A方法の両方で:

virtual ~A(); 
virtual void doWork(); 

が定義されなければならない(身体を持っている必要があります)

例:

A.cpp

void A::doWork() 
{ 
} 
A::~A() 
{ 
} 

警告:
あなたのclass Aは(C++でAbstract class a.k.a)のインターフェースとして機能する場合、あなたは仮想メソッドは純粋にする必要があります。

virtual void doWork() = 0; 

グッド読む:

What does it mean that the "virtual table" is an unresolved external?
When building C++, the linker says my constructors, destructors or virtual tables are undefined.

+0

どういう意味ですか? – rjmarques

+0

@ user1227351:詳しい説明はリンク先をご覧ください。 –

+0

仮想〜A()がある。仮想void doWork()= 0;まだvtableエラー= /を与えます。しかし、デストラクタがなければ正常に動作します。しかし、それがなければ、もし私が次のようなことをすれば:A * a = new Child();削除a;明らかにChild ::〜Child()は呼び出されません。回避策はありますか? – rjmarques

6

Aはインターフェースであることを、およびヘッダから実装コードを区切るするの私の目標です。その場合

class A { 
    // ... 
    virtual void doWork() = 0; 
}; 
+0

デストラクタも削除するとエラーがなくなります。その場合、私が行う場合: A a = new Child(); 削除a; どのデストラクタから呼び出されますか? – rjmarques

+0

破壊は常に逆順に行われます。この場合、クラス 'A'デストラクタはvirtualでなければならず、' Child'デストラクタと 'A'デストラクタが最初に呼ばれます。 'A'クラスのデストラクタが仮想でない場合、動作は未定義です。 – Mahesh

+0

親クラスのデストラクタを仮想化したので、子のデストラクタを呼び出します。その後、親クラスのデストラクタ。 – Izza

1

クラスAの仮想メンバ関数が純粋な作る他の応答のどれもがあなたを助けていない場合は任意の「* .gch」ファイルを削除することを確認します。