为什么我可以把类而不是函数在.h文件中没有得到多个定义错误
Why can I put classes and not functions in a .h file without getting the multiple definitions error?
我最近遇到了一个问题,我正在编写一个库,在。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
文件中,这是因为编译的东西必须具有预定义的类型。如果不知道它的类型,你就不能编译它。
这个故事可以写好几页…但我认为这足以解释基本的(我希望)。
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 使用命名空间时出现多个定义错误
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 在运算符重载定义中使用成员函数(const错误)
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在C++中使用内联方法时出现未定义的符号错误
- 已定义函数时出现 G++ "未定义的引用"错误
- C++ G++ 编译器 - 错误:隐式声明的定义
- 链接 cmake 时出现未定义的引用错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 错误:未定义对'oboe::AudioStreamBuilder::openStream(oboe::AudioStream**)'的引用
- 链接阶段出现多重定义错误
- 已经以性格错误定义了
- vim ctag导致了对乐趣的错误定义
- C++ 隐式声明的编译器错误定义
- 编译器错误-定义问题.C++