也许你能为我澄清一些事情,因为我不知道我的想法到底哪里有缺陷。首先是一些代码:
说话者.h:
class talker
{
public:
talker();
void sayHello() {cout << "Hello";} ;
};
Run Code Online (Sandbox Code Playgroud)
另一个类.h:
class anotherClass
{
public:
anotherClass();
void doSomethingYourself() { cout << "will do"; };
void askHimToSayHello() { pointerToTalker->sayHello; };
//Access violation, bad pointer(?)
};
Run Code Online (Sandbox Code Playgroud)
常见的.h:
static talker *pointerToTalker;
// if I add here "= new talker", code works fine
Run Code Online (Sandbox Code Playgroud)
主.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
}
Run Code Online (Sandbox Code Playgroud)
当然,函数有点复杂,每个函数都在相应的 .cpp 中实现,包括“common.h”。我的问题是 - 为什么 pointerToTalker,如果在 main() 中初始化在 anotherClass::AskHimToSayHello() 中不起作用?它应该在那里使用时指向有效内存。这是我的“世界,你好,OOP!” 顺便说一句,如果我没有希望,请保持温柔:)
对不起,幼稚的风格顺便说一句。它可以帮助我将代码减少到更紧凑的地方,而不会失去大局:)。
因为
static talker *pointerToTalker;
Run Code Online (Sandbox Code Playgroud)
不是全局的。在此上下文中,static为包含的每个翻译单元(cpp 文件 + 包含文件)提供变量内部链接common.h。
您需要将其声明为extern:
extern talker *pointerToTalker;
Run Code Online (Sandbox Code Playgroud)
并在单个实现文件中对其进行初始化。
声明它将为每个翻译单元static创建一个副本pointerToTalker。所以你从main.cpp. 其他人未初始化,因此您会遇到未定义的行为。正确的方法是:
//common.h:
extern talker *pointerToTalker;
//common.cpp
#include "common.h"
talker* pointerToTalker = new talker;
Run Code Online (Sandbox Code Playgroud)