2016-09-29 1 views
1

リスナを実装しようとしています。そのため、多くの相互参照の私は他のクラスと事前定義し、それらをクラスへのポインタを使用するとき、事前定義クラスが機能しない

次のように私のリスナーが見える

の.h

class Book 
{ 
public: 
    Book(); 
private: 
    std::vector<MyListener *> listeners_; 
    void Notify(); 
} 

た.cpp

Book::Book() {} 

void Book::Notify() { 

    MyListener *p_listener; 

    for (int i = 0; i < this->listeners_.size(); i++) { 

     p_listener = listeners_[i]; 
     p_listener->Update(); // ERRORS THROWN HERE WHEN NOT INCLUDING LISTENER.H 

    } 
} 

含めないようにしようとしていますこれは、listener.hファイルを含めるとすべて正常に動作します

#include "listener.h" 

しかし、私は代わりに、事前に宣言するリスナーは

class Listener; 

仕事doesntのそれは私に2つのエラー

C:\CPP\qtTradeSim\qtTradeSim\test\book.cpp:33: error: C2027: use of undefined type 'Listener' 
C:\CPP\qtTradeSim\qtTradeSim\test\book.cpp:33: error: C2227: left of '->Update' must point to class/struct/union/generic type 

を与えるリスナーヘッダを含めないようにする方法はありますか? class Bookのヘッダファイルで

+2

ヘッダーファイルで前方宣言する必要がありますが、実際には実装ファイルに含める必要があります。 –

+1

@AmiTavory Right。あなたのコメントをソリューションにします。 – Rene

+0

@Reneありがとう。これが重複していたが、見つけられなかったので、答えた。 –

答えて

1

はのは、コンパイラは次のコードを見ているとしましょう:

class Listener; 

std::vector<Listener*> pListeners; 

// some code... 

for(auto& pListener: pListeners) { 
    pListener->update(); 
} 

注意を、どのようにコンパイラがListenerは、メンバ関数updateを持って見ていますか?コンパイラがListener完全な宣言を参照するまで、シンボルupdateを特定できませんでした。引数がなくてupdateを使用したとしたら、コンパイラはupdateの宣言を見ずにこの問題を捕捉できますか?したがって、コードを翻訳することはできません。 Listenerという完全な宣言をした場合。

class Listener { 
public: 
    Listener() { // some construction 
    } 
    void update() { 
     // dosth 
    } 
}; 

コンパイラがupdate方法、そのパラメータ、戻り値、などを知っている、と喜んでそれをコンパイルできます。

+0

は、使用されるすべてのビットとピースを事前に宣言する必要があります。しかし、たくさんのタイピング。あまりにも悪いC + +はちょうどコンパイルする前にいくつかの事前リンクの傾き... – chrise

4

ヘッダーのみMyListenerへのポインタのstd::vectorを定義し、MyListenerの完全な申告を知っている必要はありませんので、あなたは確かに、MyListenerの前方宣言を使用する必要があります。それはそのupdateメソッドを呼び出すよう

class Bookの実装ファイルには、しかし、実際には、MyListenerの完全な申告を必要とするので、あなたはclass Bookの実装ファイルではなく、ヘッダファイルにlistener.hが含まれます。

+0

ああ、そうですね。迅速な回答ありがとう – chrise

+0

@chriseよろしくお願いします。ではごきげんよう。 –

関連する問題