2012-05-04 3 views
0

あなたの考えが間違っている場所がわからないので、私のために何かをクリアすることができるかもしれません。まず、いくつかのコード:オブジェクトへのグローバルポインタがアクセス違反を引き起こしますか?

Talker.h:

class talker  
{ 
    public: 
    talker(); 
    void sayHello() {cout << "Hello";} ; 
}; 

anotherClass.h:

class anotherClass 
{ 
    public: 
    anotherClass(); 
    void doSomethingYourself() { cout << "will do"; }; 
    void askHimToSayHello() { pointerToTalker->sayHello; }; 
          //Access violation, bad pointer(?) 
}; 

COMMON.H:

static talker *pointerToTalker;  
     // if I add here "= new talker", code works fine 

main.cppに:

#include "common.h" 
int main() 
{ 
    pointerToTalker = new talker;   // Here is the bug, but why? 
    pointerToTalker -> sayHello;    // says Hello alright 

    anotherClass *pointerToAnotherClass = new anotherClass; 
    pointerToAnotherClass -> doSomething(); //Does something OK 

    pointerToAnotherClass -> askHimToSayHello(); // Causes access violation 
} 

もちろん、関数はもう少し複雑であり、それぞれは "common.h"を含む対応する.cppに実装されています。私の質問は - なぜmainTo内で初期化された場合、pointerToTalkerはanotherClass :: AskHimToSayHello()内で動作しないのですか?それはそこで使われる時までに有効なメモリを指しているはずです。 私の "Hello world、OOP!"ですbtwので、私のための希望がない場合は優しいしてください:)

ごめんなさい子供スタイルbtw。それは私が大きな画像を失うことなく、よりコンパクトなものに持っているコードを削減するのに役立ちます:)。

答えて

4

static talker *pointerToTalker; 

はグローバルではありませんので。このコンテキストでは、staticは、common.hが含まれている各翻訳単位(cppファイル+インクルードファイル)の変数内部リンケージを提供します。

あなたはexternとしてそれを宣言する必要があります:

extern talker *pointerToTalker; 

と単一の実装ファイルでそれを初期化します。

staticを宣言すると、各翻訳単位に対してpointerToTalkerのコピーが作成されます。したがって、あなたはmain.cppから初期化しています。他は初期化されずに残されているため、の定義されていない動作に入ります。適切な方法は次のとおりです。

//common.h: 
extern talker *pointerToTalker;  

//common.cpp 
#include "common.h" 
talker* pointerToTalker = new talker;