尝试理解C++:架构x86_64的重复符号

尝试理解C++:架构x86_64的重复符号,c++,c++11,C++,C++11,以下是导致此链接器错误的文件,仅显示文件、命名空间和类名: // PubSub.hpp: #ifndef PubSub_hpp #define PubSub_hpp namespace PubSub { class Publisher {} } } #endif // Client.hpp: #ifndef Client_hpp #define Client_hpp #include "PubSub.hpp" class Client { } #endif // Scene.hpp: #if

以下是导致此链接器错误的文件,仅显示文件、命名空间和类名:

// PubSub.hpp:
#ifndef PubSub_hpp
#define PubSub_hpp
namespace PubSub {
class Publisher {}
}
}
#endif

// Client.hpp:
#ifndef Client_hpp
#define Client_hpp
#include "PubSub.hpp"
class Client {
}
#endif

// Scene.hpp:
#ifndef Scene_hpp
#define Scene_hpp
#include "Client.hpp"
class Scene {
}
#endif
代码在此状态下编译时不会出错。但只要我在PubSub.hpp中的名称空间PubSub下引入一个变量,如下所示:

// PubSub.hpp:
#ifndef PubSub_hpp
#define PubSub_hpp
namespace PubSub {
class Publisher {}
}
Publisher NetworkEventPublisher("someName");
}
#endif

我在标题中得到链接器错误。我可以找到一个解决办法,但我正在努力学习C++,所以我问这个规则是什么导致的?

错误是因为把这个头文件包含到一个以上的翻译单元中。CPP/.cc文件在翻译单元中用相同的名称AKA创建一个对象。 如果需要该类的一个实例,请在标头中将其声明为extern并在.cc文件中定义


如果每个翻译单元中都需要一个副本,请将标题中的对象声明为const并定义为const,这样的对象是隐式静态的。

发生此错误的原因是将此标题文件包含到多个翻译单元中。cpp/.cc文件会在翻译单元中创建一个具有相同名称aka符号的对象

如果需要该类的一个实例,请在标头中将其声明为extern并在.cc文件中定义

如果在每个翻译单元中都需要一个副本,那么在头中声明并定义对象为const,这样的对象是隐式静态的

但只要我在PubSub.hpp中引入一个变量

如果在多个translation unit.cpp文件中包含PubSub.hpp,则NetworkEventPublisher将被定义多次,而这正是linker所抱怨的

解决办法是:

Publisher NetworkEventPublisher("someName");
到实现文件ie.PubSub.cpp。如果您想让其他翻译单位看到它,请添加到PubSub.hpp extern声明:extern Publisher NetworkEventPublisher

但只要我在PubSub.hpp中引入一个变量

如果在多个translation unit.cpp文件中包含PubSub.hpp,则NetworkEventPublisher将被定义多次,而这正是linker所抱怨的

解决办法是:

Publisher NetworkEventPublisher("someName");

到实现文件ie.PubSub.cpp。如果您想让其他翻译单位看到它,请添加到PubSub.hpp extern声明:extern Publisher NetworkEventPublisher

不要在标题中定义对象。比预期短:-谢谢。相关:。特别是关于静态变量,答案也涵盖了您的情况:对头文件实际作用的误解。不要在头文件中定义对象。比预期的短:-谢谢。相关:。特别是关于静态变量,答案也涵盖了您的情况:对头文件实际作用的误解。假设他以后要修改对象,是否可以声明为静态?@bkVnet是可能的。假设他以后要修改对象,是否可以声明为静态?@bkVnet是可能的。