C++ Multiply Defined constructor 错误消息似乎是错误的

Posted

技术标签:

【中文标题】C++ Multiply Defined constructor 错误消息似乎是错误的【英文标题】:C++ Multiply Defined constructor error message seems wrong 【发布时间】:2017-08-13 20:09:15 【问题描述】:

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) 

【问题讨论】:

缺少标题包括警卫? 这可能会有所帮助。 ***.com/questions/12573816/…. @user0042 :警卫在那里。 @R Sahu:链接处理未定义的符号。这是一个双重定义的符号。 @ArthurSchwarez 请提供minimal reproducible example。 @ArthurSchwarez - 你有 not 在你的代码 sn-ps 中显示“标题包含”保护,而不是在任何一个文件中。您是否建议它们在您的代码中?如果是这样,你为什么不包括他们?标头保护是开发人员选择的格式。对于文件 NodeClass.h,我的将是“#ifndef NODECLASS_H”。 【参考方案1】:

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


有 2 种类型的包含警卫。我见过两者都使用过,但同时使用的次数较少。都是条件编译命令的例子。

在名为“NodeClass.h”的头文件中,我的头文件保护版本的前两行和最后一行(条件编译示例)如下:

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


【讨论】:

为什么要测试 .cc 文件中的包含保护? @MM 偏执狂?你没有修改 .h 文件的权限(政治?)你有这样做的命令(尖尖的头发经理 - 我没见过,但我想他们确实存在)我的想象力失败了。 @SahibYar - 如果单独的编译单元都定义“anything()”(通过包含 OP 的相同标头),并且这两个(或更多)编译单元输出随后链接在一起,这确实会导致在多个定义错误中,包括警卫没有提供解决方案。该问题中的示例显示了一个定义为“anything()”的头文件,而不仅仅是“anything()”的声明。审查:声明与定义(即头与代码)。错误是带有定义的头文件被拉入多个编译单元并链接。 @SahibYar - w.r.t 您的参考:A)链接器检测到违反 ODR(一个定义规则)B)放置在具有任意数量声明的标头中的函数定义仍然是定义 C)' #include' 复制 @moen 感谢您指出另一个头后卫。我学会了!请注意,我从来没有想过使用它,但如果没有你告诉我“它”是什么,我不会知道“我永远不会想到使用它”。谢谢【参考方案2】:

我怀疑您在标题中对这些函数进行了离线定义。

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

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

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

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

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

【讨论】:

以上是关于C++ Multiply Defined constructor 错误消息似乎是错误的的主要内容,如果未能解决你的问题,请参考以下文章

fatal error LNK1169: one or more multiply defined symbols found

c语言编译时one or more multiply defined symbols found 。刚学c求大侠帮忙看看

vc++编译通过了.但生成exe文件时出现了one or more multiply defined symbols found请问可能是啥原因啊

stm32错误解释o.axf: Error: L60E: Symbol GPIO_InitStructure multiply defined (by httpd.o and main.o

#if defined的介绍

关于#if defined和#ifdef