C++ 乘法定义的构造函数错误消息似乎错误

C++ Multiply Defined constructor error message seems wrong

本文关键字:错误 消息 构造函数 定义 C++      更新时间:2023-10-16

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) {}

您没有提供足够的信息来自信地识别编译错误。 我同意,在没有足够和适当的包括警卫的情况下,可能会发生双重定义。 您没有显示包含保护,并且您的错误在上面的代码中并不明显,


有 2 种类型的包含防护装置。 我见过两者都使用,但同时使用的频率较低。 所有这些都是条件编译命令的示例。

在名称为"NodeClass.h"的头文件中,我的标头保护版本将具有以下内容的前 2 行和最后一行(条件编译示例(:

#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                   // <---

在代码文件中,名称为"NodeClass.cc",我的标头保护的第二个版本将包含类似的条件编译语句。 这在大多数环境中较少使用,我更喜欢上述环境。

#ifndef NODECLASS_H   
#include "NodeClass.h"
#endif
#include <vector>     // <-- redundant since also in header
using namespace std;
using namespace slip;
NodeClass::NodeClass(vector<string*>& vec) 
: SlipPointer(new string("Cluster Node"))
, vec(vec) 
{
}

我怀疑你的标题中有这些函数的外联定义。

初始化列表 是构造函数定义的一部分,因此您需要在定义构造函数主体的同一位置定义它。这意味着您应该必须在头文件中执行此操作:

NodeClass(vector<string*>& vec) :
SlipPointer(new string("Cluster Node")), vec(vec) {}

由于构造函数的定义不是内联的,因此编译器不会使其隐式内联。现在,如果在多个翻译单元(即 *.cpp 文件(中包含相同的文件,链接器将生成您看到的错误,因为每个 *.cpp 文件都将包含其自己的构造函数定义,而不会将它们标记为内联函数。

另一种简单的解决方案只是在构造函数声明前面放一个内联:

public:
inline NodeClass(vector<string*>& vec);