为什么我可以在没有多重定义错误的情况下将类而不是函数放在.h文件中?

时间:2016-09-10 00:40:14

标签: c++

我最近遇到一个问题,我在.h文件中编写了一个包含大量函数定义的库,并且随着库变得更加相互依赖,我开始遇到很多函数错误的多个定义,所以为了减少重构,我声明了我的所有功能都是内联的,但是我想知道为什么我不必为同一个.h文件中定义的类改变任何东西?这些课程也不应该重复吗?

2 个答案:

答案 0 :(得分:2)

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

类是特殊的,你可以在多个翻译单元中定义它们,只要每个副本的内容完全相同 - 这个特殊规则很重要,否则你的类不会很有用;只有声明的类不能立即使用,而只声明的函数可以立即用于任何东西。

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

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

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

答案 1 :(得分:1)

您也可以将函数放在.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个文件中,因为编译的东西必须是预定义的类型。你不能在不知道它是什么类型的情况下编译一些东西。

故事可以用于页面......但我认为这足以解释基础知识(我希望)。