gcc版本5.4.0(GCC)
> g++ -std=c++11
在构建期间,我得到一个类构造函数的多重定义错误消息。当我删除构造函数时,我得到一个未定义的符号错误消息。我很难过。
NodeClass::NodeClass( ... )
标记为
错误消息:
build/Debug/Cygwin64-Windows/nodeClass.o: In function `__gnu_cxx::new_allocator<std::string*>::~new_allocator()':
/c/home/skidmarks/Projects/MPHASH/mphash/NodeClass.cpp:36: multiple definition of `NodeClass::NodeClass(std::vector<std::string*, std::allocator<std::string*> >&)'
build/Debug/Cygwin64-Windows/NodeClass.o:/c/home/skidmarks/Projects/MPHASH/mphash/NodeClass.cpp:36: first defined here
标题文件:
# include <vector>
# include <gslip/SlipPointer.h>
class NodeClass : public SlipPointer
{
private:
vector<string*> vec;
public:
NodeClass(vector<string*>& vec);
virtual ~NodeClass() { };
private:
NodeClass(const NodeClass& orig) { };
};
源代码:
# include <vector>
# include "NodeClass.h"
using namespace std;
using namespace slip;
NodeClass::NodeClass(vector<string*>& vec) :
SlipPointer(new string("Cluster Node")), vec(vec) {}
答案 0 :(得分:0)
您没有提供足够的信息来自信地识别您的编译错误。我同意如果没有足够和适当的包含警卫,可能会发生双重定义。您没有显示包含警戒,并且您的错误在上面的代码中不明显,
有两种类型的包含警卫。我已经看到了两种情况,但不太常见。所有都是条件编译命令的例子。
在名为“NodeClass.h”的头文件中,我的头文件防护版本将包含以下内容的前2行和最后一行(条件编译示例):
map
在代码文件中,名称为“NodeClass.cc”,我的第二个版本的头文件将包含类似的条件编译语句。这在大多数环境中使用较少,我更喜欢上述内容。
#ifndef NODECLASS_H // <--- header include guard
#define NODECLASS_H // <---
#include <vector>
#include <gslip/SlipPointer.h>
class NodeClass : public SlipPointer
{
private:
vector<string*> vec;
public:
NodeClass(vector<string*>& vec);
virtual ~NodeClass() { };
private:
NodeClass(const NodeClass& orig) { };
};
#endif // <---
答案 1 :(得分:0)
我怀疑你在标题中有这些功能的外线定义。
初始化列表 是构造函数定义的一部分,因此您需要在定义构造函数体的同一位置定义它。这意味着您必须在头文件中执行此操作:
NodeClass(vector<string*>& vec) :
SlipPointer(new string("Cluster Node")), vec(vec) {}
由于构造函数的定义在类定义中不是内联的,因此编译器不会隐式内联。现在,如果您在多个翻译单元中包含相同的文件(即* .cpp文件),链接器将产生您看到的错误,因为每个* .cpp文件将包含其自己的构造函数定义,而不会标记它们作为内联函数。
替代简单的解决方案就是在构造函数声明的前面放置一个内联:
public:
inline NodeClass(vector<string*>& vec);