代码之家  ›  专栏  ›  技术社区  ›  wrongusername

多重重定义错误

  •  2
  • wrongusername  · 技术社区  · 15 年前

    在了解了更多关于类和指针的知识之后,我重构了一个我拥有的程序,并删除了200行代码,在创建另外两个类的过程中, Location 和 Piece . 问题是,在编译完所有内容之后,链接器会抱怨 片 定义了多次,其中包含错误:

    In function 'Piece':                                         board.o
    multiple definition of 'Piece::Piece(int)`                   char_traits.h
    In function 'Piece':                                         board.o
    multiple definition of 'Piece::Piece(int)`                   piece.cpp
    In function 'Piece':                                         player.o
    multiple definition of 'Piece::Piece(int)`                   piece.cpp
    In function 'Piece':                                         player.o
    multiple definition of 'Piece::Piece(int)`                   piece.cpp (yes, same exact error!)
    In function 'Piece':                                         refereee.o
    multiple definition of 'Piece::Piece(int)`                   char_traits.h
    In function 'Piece':                                         referee.o
    multiple definition of 'Piece::Piece(int)`                   piece.cpp
    ...
    

    当我点击错误 char_traits.h ,这让我想到:

    static size_t
    length(const char_type* __s) //error points here to line 262
    { return __builtin_strlen(__s); }
    

    另一个 特征.h 带我到

      static int
      compare(const char_type* __s1, const char_type* __s2, size_t __n) //line 258, error points here too
      { return __builtin_memcmp(__s1, __s2, __n); }
    

    正如你所知道的,location.h是唯一包含piece.h(其他文件包括piece.h)的东西,board.h是唯一包含location.h的东西,还有一堆类包括board.h

    我试着把护头改成 _OTHELLO_PIECE_H ,并尝试将类重命名为opiece(通过IDE)。都没有解决问题。

    有趣的是,其中一个错误有一个“in-function”opiece“:”,然后我的IDE将 chatter.o 即使chatter.h和chatter.cpp都不包含任何包含opiece的内容。

    知道是什么导致了这个重新定义错误吗?

    5 回复  |  直到 15 年前
        1
  •  4
  •   Dialecticus    15 年前
    1. 重建一切
    2. 查找piece::piece,并从头文件中删除所有此类项 2b.从不包含.cpp文件
    3. 寻找可分解为块的定义
        2
  •  2
  •   aschepler    15 年前

    多函数定义错误的最常见原因是将函数定义放在头文件中,然后忘记将其设置为 inline 。

    我不太担心 char_traits.h -这可能意味着由于某些模板狭条排印,链接器无法找到更好的位置来声明定义发生在特定的对象文件中。

        3
  •  1
  •   sth    15 年前

    您应该将构造函数的实现放在 piece.cpp ,不直接在 piece.h 。

        4
  •  1
  •   justin    15 年前

    有两个地方要实施 Piece::Piece(int) 在典型结构中:

    1)接口(AT声明)

    class Piece {
        int d_a;
    public:
        Piece(int a) : d_a(a) {
        }
        /* ... */
    };
    

    2)在专用CPP文件中

    整体式水电站

    class Piece {
        int d_a;
    public:
        Piece(int a);
        /* ... */
    };
    

    整块.cpp

    Piece::Piece(int a) : d_a(a) {
    }
    

    但是,模板的定义不同。

    这个错误经常表明 Piece::Piece(int a) : d_a(a) {} 包含在多个cpp文件中。

    生成的每个对象文件都会添加符号 件:件(int) 在可见的地方。

    在构建结束时,所有对象都被合并/链接,以创建最终的二进制文件或可执行文件。然后链接器会看到这个定义的副本,并产生一个错误。

    诊断这一问题的一个快速方法是(假设构建不会花费很长时间):

    #warning Piece::Piece(int) is visible here
    Piece::Piece(int a) : d_a(a) {
    }
    

    只应发出一个警告。如果发出更多信息,那么编译器可能会提供一些信息(例如include顺序)。

        5
  •  0
  •   towi    15 年前

    只是猜测一下:你用过 #include 或者你用过 #import 不小心——我曾经遇到过一次——)

    推荐文章