class 主体外定义的 C++ 成员函数的编译
Compilation of C++ member functions defined outside the class body
我有这样一个 hpp 文件:
#ifndef __MYLIB_H
#define __MYLIB_H
class A {
public:
void func1();
void func2();
};
void A::func1() {
// maybe do something
}
#endif
对应的cpp文件中有func2的实现。头文件包含在项目中的其他文件中(这些文件包含在更多文件中)。当我尝试构建它时,我收到 func1
的 "multiple definition" 链接器错误。为什么会这样?因为我用#ifndef
保护了头文件,没想到会报错
如果我在 func1
的定义中添加关键字 inline
,那么一切都很好。所以如果我不关心被内联的函数并且我不想在 class 主体中有定义,我不能在 hpp 文件中包含它的定义?如果有人可以解释这里发生了什么,那将非常有帮助。我正在使用 GCC 6。
实现通常放在相关的 .cpp
文件中。将它们放在 header 中是有问题的。 inline
是一种解决此问题的 hack,您可能不想使用它,因为它会在该代码出现的任何地方都将其删除,从而导致大量重复。
请记住,#include
非常类似于将该文件粘贴到该指令出现的代码中。一个函数有多个实现是不正确的,这就是为什么它们在 header 之间分开用于签名目的,因此理解如何正确使用这些函数,以及实际代码的实现。
问题是您在每个文件中重新定义 func1
。
#include
指令是一个非常简单的命令,它只是将 header 文件的内容粘贴到指定的位置。
这样做的结果是,每次您 #include
您的 header 您在该文件中 "redefining" func1
。
回想一下,整个 header 的内容以及它可能包含的任何文件实际上都 "copy-pasted" 到每个 翻译单元* 在包含点包含 header。
这就是为什么在多个 CPP 文件中包含 header 的效果与将 copy-pasted 函数定义字面意思写入每个 CPP 的效果相同,即它与编写多个相同相同 member-function.
的相同定义
通过声明函数inline
解决了问题,因为C++允许定义多个内联函数,只要它们彼此相同即可。将函数的 body 移动到 class 的声明中也可以,因为这样的函数会被自动视为 inline
.
* 在这种情况下,"translation unit" 是您的 CPP 文件的奇特名称。
我有这样一个 hpp 文件:
#ifndef __MYLIB_H
#define __MYLIB_H
class A {
public:
void func1();
void func2();
};
void A::func1() {
// maybe do something
}
#endif
对应的cpp文件中有func2的实现。头文件包含在项目中的其他文件中(这些文件包含在更多文件中)。当我尝试构建它时,我收到 func1
的 "multiple definition" 链接器错误。为什么会这样?因为我用#ifndef
保护了头文件,没想到会报错
如果我在 func1
的定义中添加关键字 inline
,那么一切都很好。所以如果我不关心被内联的函数并且我不想在 class 主体中有定义,我不能在 hpp 文件中包含它的定义?如果有人可以解释这里发生了什么,那将非常有帮助。我正在使用 GCC 6。
实现通常放在相关的 .cpp
文件中。将它们放在 header 中是有问题的。 inline
是一种解决此问题的 hack,您可能不想使用它,因为它会在该代码出现的任何地方都将其删除,从而导致大量重复。
请记住,#include
非常类似于将该文件粘贴到该指令出现的代码中。一个函数有多个实现是不正确的,这就是为什么它们在 header 之间分开用于签名目的,因此理解如何正确使用这些函数,以及实际代码的实现。
问题是您在每个文件中重新定义 func1
。
#include
指令是一个非常简单的命令,它只是将 header 文件的内容粘贴到指定的位置。
这样做的结果是,每次您 #include
您的 header 您在该文件中 "redefining" func1
。
回想一下,整个 header 的内容以及它可能包含的任何文件实际上都 "copy-pasted" 到每个 翻译单元* 在包含点包含 header。
这就是为什么在多个 CPP 文件中包含 header 的效果与将 copy-pasted 函数定义字面意思写入每个 CPP 的效果相同,即它与编写多个相同相同 member-function.
的相同定义通过声明函数inline
解决了问题,因为C++允许定义多个内联函数,只要它们彼此相同即可。将函数的 body 移动到 class 的声明中也可以,因为这样的函数会被自动视为 inline
.
* 在这种情况下,"translation unit" 是您的 CPP 文件的奇特名称。