2

为什么在头文件中定义类的函数是一种不好的做法?

假设我有一个头文件,我在类定义本身中定义了类的函数,例如,

头文件.hpp

#ifndef _HEADER_FILE_
#define _HEADER_FILE_

class node{
int i;

public:
int nextn(){
......
return i;
}
}

#endif //_HEADER_FILE_

所以像这样在类中定义函数会使函数“内联”。所以如果我们在两个 .cpp 文件中包含这个头文件,会导致“多重定义错误”吗?定义这样的函数是一种不好的做法这在类定义中?

4

4 回答 4

5

这是一个不好的做法,原因如下: 如果您需要更改代码,假设在简单的 setter 中添加跟踪(它们通常在 .h 中);那么您将需要重新编译所有 #includes 更改(以及任何依赖项)的 CPP 文件。在我目前的项目中,最多可能会损失 1 小时。如果您稍后需要添加另一个跟踪,那么另一个等等您很快就会松动 1-2 天或等待编译器工作。

如果您将代码放在 CPP 中,那么您只需要重新链接,并且只需几分钟。你今天的项目可能很小,但几年后谁知道。这只是一个好习惯。

另一个(不太好)的原因是,如果您在代码库中搜索字符串“::MyFonction”,您将不会在声明中找到它,因为没有“::”(我们只需要实现)。但是一个好的 IDE 无论如何都应该使用上下文搜索而不是字符串搜索来找到它。

于 2013-12-13T15:16:12.760 回答
2

这不是坏习惯(事实上它很普遍),它不会导致多个定义错误。内联函数永远不会导致多个定义错误,这就是内联的含义之一。

于 2013-09-28T08:01:24.353 回答
1

将原型(即类的声明、其函数、它们的类型)与实现分开的约定来自设计和性能的观点。

  • 类型检查和编译你的家属更便宜。使用你的类的东西可以在不知道你的实现的情况下安全地编译。

  • 每次编译这些依赖项时,您的编译器都不需要多次解析和重新编译相同的信息。

关键是要记住在 C++ 中写在文件顶部的真正含义#include:它的意思是“获取其他文件的所有内容,并将它们放在这里”。因此,如果您在整个代码库的很多地方都使用了一个类,那么它每次都会被解析,并在该编译单元的上下文中重新编译。

这正是您必须模板类的实现嵌入到头文件中的原因;编译器需要为每个不同的模板实例化重新解析和编译类(因为这就是模板的意义所在)。

直接回答您的问题: * 不,您不会收到多重定义错误。* 也许,有些人会从设计的角度将其视为实践(其他人不会) * 您可能会看到性能上的差异(尽管我认为不一定是退化 - 尽管我可能是错的),尽管以上,编译仅头文件库仍然可以更快。

如果您的实现很长,可能避免这样做,该类经常在代码库中使用,并且会经常更改。

为了进一步阅读,可能值得检查“预编译的标头”。

于 2013-09-28T10:22:10.830 回答
0

在 hpp 文件中定义(内联)函数是合法的。请注意,有些人喜欢在诸如“inl.hpp”之类的专用扩展名下进行收集,但这只是一种风格偏好。

于 2013-09-28T08:24:31.137 回答