【问题标题】:Redefinition error: Different .h files using the same class name重定义错误:不同的.h文件使用相同的类名
【发布时间】:2016-11-29 04:07:56
【问题描述】:

我创建了 2 个头文件。 ListA.h 和 ListN.h

他们都自己使用自己独特的类列表。当我编译我的程序时(即使他们无法知道另一个存在,它会说以下错误)

我很确定它不应该是一个重新定义,但它显然是。任何帮助表示赞赏。


ListA.h

#ifndef __LISTA_H_
#define __LISTA_H_
#include <iostream>

using namespace std;
class List{
        public:
              List(int = 0);
              List(const List&);
              ~List();
};   
#endif

ListN.h

#ifndef __LISTN_H_
#define __LISTN_H_
#include <iostream>

using namespace std;

class List{
        public:
              List(int = 10);
              List(const List&);
              ~List();
};    
#endif

ListA.cpp

#include "ListA.h"
using namespace std;

List::List(int mySize)
{
    //...
}

ListN.cpp

#include "ListN.h"
#include <iostream>
using namespace std;
List::List(int size)
{
    //...
}

主要

#include <iostream>
#include "ListN.h"
using namespace std;

int main()
{
    List myList;
    return 0;
}

【问题讨论】:

  • 他们都在同一个项目中,这可能与它有关。
  • [basic.def.odr] "给定一个名为 D 的实体在多个翻译单元中定义,那么 D 的每个定义都应包含相同的标记序列..." 您违反了这条规则,因为您在不同的翻译单元中定义了一个名为 List 的实体。

标签: c++ class scope redefinition


【解决方案1】:

编译器正在编译两个 cpp 文件。因此,当链接器将文件链接在一起时,它会感到困惑,因为有多个 List 类。

要解决此问题,您可以使用命名空间,或者您不公开至少一个 List 类。


或者,如果这个想法是为了配置目的能够包含 ListN.hListA.h,那么这样做是错误的。要么你应该有一个#define 参数作为标题,或者你应该找到一些其他的方式,比如通过#ifdef。例如(我不是 100% 确定这会编译,但你明白了):

List.h

#ifndef __LIST_H_
#define __LIST_H_

#ifndef LIST_PARAM
#define LIST_PARAM 0
#endif

#include <iostream>

using namespace std;

class List{
        public:
              List(int = LIST_PARAM);
              List(const List&);
              ~List();
};    
#endif

ma​​in.cpp

#include <iostream>

#define LIST_PARAM 10
#include "List.h"

using namespace std;

int main()
{
    List myList;
    return 0;
}

我个人不喜欢这种方法;将值传递给构造函数会更好:

int main()
{
    List myList{ 10 };
    return 0;
}

【讨论】:

    【解决方案2】:

    当链接器尝试链接查找列表的定义/符号时,它确实在两个不同的 obj 文件中找到,因此链接器给出错误。在视觉工作室错误号:LNK2005

    要解决此错误,可以:

    1. 要修复,请将/FORCE:MULTIPLE 添加到链接器命令行选项
    2. 在两个不同的命名空间中添加类可以避免这个错误。

    ListN.h

    #ifndef __LIST_H_
    #define __LIST_H_
    #include <iostream>
    
    using namespace std;
    
    namespace ListN
    {
      class List{
      public:
          List(int = 10);
          List(const List&);
      };
    }
    
    #endif
    

    ListN.cpp

    #include "ListN.h"
    #include <iostream>
    
    using namespace std;
    
    namespace ListN
    {
      List::List(int size)
      {
          //...
      }
    }
    

    Main.cpp

    #include <iostream>
    #include "ListN.h"
    int main()
    {
      ListN::List myList;
      return 0;
    }
    

    【讨论】:

    • 现在主文件说 List 没有在范围内声明
    • 在用户之前使用命名空间,例如我的情况 ListN::List。或使用命名空间 ListN 添加。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2020-10-20
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多