我正在阅读有关内联函数的信息,以及它们如何在不同的翻译单元中具有多个定义,但这些定义必须相同。
所以我在想的是,如果我在头文件中声明一个函数并在 2 个 cpp 文件中将其定义为内联,编译器就不会生气。
所以我尝试执行以下操作:
全球.h
#ifndef DRAKOS_GLOBAL_H
#define DRAKOS_GLOBAL_H
#include <iostream>
void fct();
#endif //DRAKOS_GLOBAL_H
文件1.cpp
#include "global.h"
inline void fct()
{
std::cout << "file1.cpp n";
}
主.cpp
#include "global.h"
extern void fct();
int main()
{
fct();
}
建筑--->错误:
对"fct()"的未定义引用
好的,我在谷歌中环顾四周,我读到了
必须将函数的定义放在标头中 文件,除非该函数仅在单个.cpp文件中使用。
到目前为止,一切都清晰而合乎逻辑,但问题是,如果我把定义放在头文件中;每个 TU 都有相同的定义,我将无法定义内联函数的两个版本,比如一个在 file1.cpp TU 中,第二个在主.cpp TU 中。
所以问题 1 :为什么他们说,对于内联函数,可以在不同的 TU 中有多个定义,但必须相同(就像我把定义放在标题中一样,它会在 cpp 文件中做不同的事情)
问题 2 : 如果可以这样做并定义 inled 函数的多个定义(由于我这边的理解不足),请给我看一个简单的例子:)
提前致谢
由于规则 C++17 [dcl.inline]/6,此代码会导致未定义的行为(无需诊断):
[...] 如果具有外部链接的函数或变量在一个翻译单元中内联声明,则应在其出现的所有翻译单元中内联声明;无需诊断。
您已fct
file1.cpp
中声明内联,但未在main.cpp
中声明。
此外,您在main.cpp
中对fct
没有任何定义。您可以复制并粘贴到main.cpp
(以及项目中的所有其他.cpp):
inline void fct()
{
std::cout << "file1.cpp n";
}
但这将是不好的做法,因为意外更改其中一个功能或忘记.cpp文件会更容易。将其放在头文件中可以避免此问题。