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 
} 

Конечно, функции немного сложнее, и каждый из них реализуется в соответствии с .cpp, включая «common.h». Мой вопрос: почему pointerToTalker, если инициализирован внутри main(), не работает внутри anotherClass :: AskHimToSayHello()? Он должен указывать на действительную память к моменту ее использования там. Это мой «Привет мир, ООП!» Кстати, будьте любезны, если нет надежды на меня :)

Извините за детский стиль кстати. Это помогает мне сократить код, который у меня есть для чего-то более компактного, если я не потеряю большую картину :).

ответ

4

Поскольку

static talker *pointerToTalker; 

не является глобальным. В этом контексте static дает переменную внутреннюю связь для каждой единицы перевода (файл cpp + включенные файлы), в который включен common.h.

Вы должны объявить его как extern:

extern talker *pointerToTalker; 

и инициализировать его в одном файле реализации.

Объявление об этом static создаст копию pointerToTalker для каждой единицы перевода. Итак, вы инициализируете один из main.cpp. Другие остаются неинициализированными, и поэтому вы сталкиваетесь с неопределенным поведением. Правильный путь:

//common.h: 
extern talker *pointerToTalker;  

//common.cpp 
#include "common.h" 
talker* pointerToTalker = new talker; 
Смежные вопросы