C++ &引用;“的多重定义”&引用;首先在此处定义”的含义;在数据结构的同一行中

C++ &引用;“的多重定义”&引用;首先在此处定义”的含义;在数据结构的同一行中,c++,data-structures,header-files,C++,Data Structures,Header Files,在发布这篇文章之前,我读过很多文章,我找不到解决方案,因为其中没有一篇(我读过的)是关于数据结构的 我有两个数据结构(如果有关系的话,一个堆和一个UF) 它们都在.h文件中实现。 我只在类外实现的成员函数(如int UnionFind::Find(int I))上得到“多重定义…”“首次定义在此处”错误 c'TOR和d'TOR也会发生这种情况,但当我在类本身中实现它们时,它就消失了。 我真的不知道为什么会这样 我在所有文件中都遵循了include,没有双重include或循环 我还使用了一个AV

在发布这篇文章之前,我读过很多文章,我找不到解决方案,因为其中没有一篇(我读过的)是关于数据结构的

我有两个数据结构(如果有关系的话,一个堆和一个UF)
它们都在.h文件中实现。 我只在类外实现的成员函数(如
int UnionFind::Find(int I)
)上得到“多重定义…”“首次定义在此处”错误
c'TOR和d'TOR也会发生这种情况,但当我在类本身中实现它们时,它就消失了。 我真的不知道为什么会这样
我在所有文件中都遵循了include,没有双重include或循环

我还使用了一个AVL树,它并没有发生在那里,所有的东西都是在类之外的.h文件中实现的

以下是我收到的错误:

/tmp/ccp8fP73.o: In function `UnionFind::Find(int)':
main.cpp:(.text+0x0): multiple definition of `UnionFind::Find(int)'
/tmp/ccVxSiPy.o:Elections.cpp:(.text+0x0): first defined here
/tmp/ccp8fP73.o: In function `UnionFind::Union(int, int)':
main.cpp:(.text+0x108): multiple definition of `UnionFind::Union(int, int)'
/tmp/ccVxSiPy.o:Elections.cpp:(.text+0x108): first defined here
如果你需要更多的信息,请告诉我。
谢谢你

如果我理解正确,你正在做这样的事情:

// C.h

class C
{
   void f(); // declaration of f; ok to include in many modules
};

// definition of f; must not exist in more than one module
void C::f()
{
}
这是行不通的,因为
f()
的定义将出现在包含C.h的每个模块中,从而导致您描述的链接器错误。您可以通过将
f()
标记为
inline
,或将
f()
的定义移动到单独的cpp文件来解决此问题

有一种特殊情况允许这样做,那就是
f()
是一个模板(直接或因为
C
是一个模板)。在这种情况下,定义必须在头中,这样编译器就可以知道如何为您指定的任何类型实例化它。这确实会给链接器带来困难,因为您可以而且经常会得到一些通常是错误的冗余定义(例如,如果您在多个模块中使用
f()
)。需要特殊的行为来处理这个问题


顺便说一句,在类定义中移动函数体时工作正常的原因是,这样做会使它们隐式内联。

如果我理解正确,您会这样做:

// C.h

class C
{
   void f(); // declaration of f; ok to include in many modules
};

// definition of f; must not exist in more than one module
void C::f()
{
}
这是行不通的,因为
f()
的定义将出现在包含C.h的每个模块中,从而导致您描述的链接器错误。您可以通过将
f()
标记为
inline
,或将
f()
的定义移动到单独的cpp文件来解决此问题

有一种特殊情况允许这样做,那就是
f()
是一个模板(直接或因为
C
是一个模板)。在这种情况下,定义必须在头中,这样编译器就可以知道如何为您指定的任何类型实例化它。这确实会给链接器带来困难,因为您可以而且经常会得到一些通常是错误的冗余定义(例如,如果您在多个模块中使用
f()
)。需要特殊的行为来处理这个问题


顺便说一句,在类定义中移动函数体时工作正常的原因是,这会使它们隐式内联。

如果要手动创建模板

//一,。包括模板代码

#include <template/list.tmpl.c>
#包括
//二,。实例化使用它的实例

#include "/c/viewer/src/ViewObject.h"
#include "/c/viewer/src/WindowAdaptor.h"
template class List<ViewObject>;
template class List<WindowAdaptor>;
#包括“/c/viewer/src/ViewObject.h”
#包括“/c/viewer/src/windowadapter.h”
模板类列表;
模板类列表;

如果要手动创建模板

//一,。包括模板代码

#include <template/list.tmpl.c>
#包括
//二,。实例化使用它的实例

#include "/c/viewer/src/ViewObject.h"
#include "/c/viewer/src/WindowAdaptor.h"
template class List<ViewObject>;
template class List<WindowAdaptor>;
#包括“/c/viewer/src/ViewObject.h”
#包括“/c/viewer/src/windowadapter.h”
模板类列表;
模板类列表;

是否包含.cpp文件而不是.h?不能在标头中定义类外的函数,除非它们已模板化或显式标记为内联。否则你会得到你所看到的错误。。AVL确实是模板化的。。多谢各位。您能解释一下为什么我不能这样做吗?您是否包括.cpp文件而不是.h?您不能在标头中定义类外的函数,除非它们被模板化或显式标记为内联。否则你会得到你所看到的错误。。AVL确实是模板化的。。多谢各位。你能解释一下为什么我不能那样做吗?