为什么我可以把类而不是函数在.h文件中没有得到多个定义错误

Why can I put classes and not functions in a .h file without getting the multiple definitions error?

本文关键字:错误 定义 文件 我可以 函数 为什么      更新时间:2023-10-16

我最近遇到了一个问题,我正在编写一个库,在。h文件中有很多函数定义,随着库变得更加相互依赖,我开始遇到很多函数错误的多个定义,所以为了减少重构,我将所有函数声明为内联,但我想知道为什么我不必为相同的。h文件中定义的类改变任何东西?类不也应该被复制吗?

您可以在头文件中声明变量、函数和类,并将该头文件包含到多个翻译单元中,没有问题。但是你所做的是定义函数,这是不同的。

类的特殊之处在于你可以在多个翻译单元中定义它们,只要每个拷贝的内容完全相同 —这个特殊的规则很重要,因为否则你的类就不会很有用;一个只被声明的类不能立即用于很多用途,而一个只被声明的函数可以立即用于几乎任何用途。

这只是两种事物不同性质的结果。

// Declarations
extern int x;  // variable
void foo();    // function
class T;       // class
// Definitions
int x;         // variable
void foo() {}  // function
class T {};    // class

您也可以将函数放在.h文件中,但也只能将函数定义;不是声明,除非是模板函数。所以基本上它和类的规则是一样的,除了对于类,如果你用一种快速而肮脏的方式,你把所有的东西都放在类本身里面,你把定义和声明结合起来,这不是很好的实践。

:

进入。h文件:

int DoSomething(double x, double y);

这是。cpp文件

int DoSomething(double x, double y)
{        
    return static_cast<int>(x+y);
}

虽然这(如果你关心模板,否则就忽略它),只能到一个。h文件:

template <typename T>
int DoSomething(T x, T y)
{        
    return static_cast<int>(x+y);
}

这整件事不是为了好玩。有一个很好的理由。原因是.h文件代表一个API,而.cpp文件代表一个实现。理想情况下,API是您提前计划并且永远不会更改的东西。另一方面,可以更新实现以修复错误,例如。

cpp文件可以编译成动态链接库(dll)或共享库,然后可以在不修改API的情况下更新。所以你可以在你的程序中使用相同的API包括一些.h文件,并链接它到不同的实现,如果你喜欢。

如果你问:为什么模板只能在.h文件中,这是因为编译的东西必须具有预定义的类型。如果不知道它的类型,你就不能编译它。

这个故事可以写好几页…但我认为这足以解释基本的(我希望)。