c++ - 可以在头文件中定义一个很长的类函数成员吗?

标签 c++ class inline

我在头文件中定义了一个类,并在同一个头文件中实现了它的功能。我没有在函数定义中放置 inline 关键字,因为我认为默认情况下编译器会将其视为内联函数——但 inline 只是对编译器的提示,对吧?如果编译器因为它的长度而不将其视为内联函数怎么办?我在现实中从未收到错误消息“多个定义”。

struct tmp {
    void print() {
       ...(very long)
     }
};

最佳答案

I didn't put inline keyword with function definition because I think compiler will regard it as a inline function by default

是的,在类主体中定义的成员函数是隐式内联。关键字不是必需的。

inline is only a hint to compiler, right? What if compiler doesn't regard it as inline function because of its length?

是的,有点。实际上,inline 关键字有两个含义。

第一个是您正在考虑的那个,提示优化器在调用站点的函数体中内联代码的那个。正如您所说,这只是一个提示——如果优化器确定这样做会导致性能悲观(或者由于其他技术原因无法内联),则优化器可以随意忽略此请求。 inline 关键字的这种含义可以说已经过时了。现在所有的优化编译器都忽略了 inline 关键字,因为它们的作者认为他们的启发式方法比程序员更聪明。这种情况几乎总是如此,因此通过将函数标记为内联来尝试和猜测优化器变得毫无意义。

inline 关键字的第二个含义是放宽单一定义规则 (ODR),使链接器可以看到同一函数的多个定义是合法的。 (虽然链接器在这种情况下的行为是一个实现细节,但它们中的大多数只会任意选择一个定义。当然,只有在它们都相同的情况下才能很好地工作。) inline 关键字的这个含义仍然是非常重要,并解释了为什么它今天仍在代码中使用。

这就是您的代码受益的含义。由于在类主体中定义的成员函数被隐式标记为内联,因此您不会从链接器中获得多重定义的符号错误。

如果您在头文件中定义了函数但没有在类定义中——换句话说,如果您这样做了:

struct tmp {
    void print();
};

void tmp::print()
{ ... }

一旦该头文件包含在两个或多个编译区(,翻译单元)中,您就会开始收到多重定义的符号错误。这是您需要在函数定义中添加 inline 关键字的地方,不是因为您希望编译器“内联”它,而是因为您想免除 ODR。

关于c++ - 可以在头文件中定义一个很长的类函数成员吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37810742/

相关文章:

c++ - 有人可以告诉我这是如何在 main() 中实现的吗? (关于void指针的问题)

C++如何监听HTTP请求

c++ - Xcode 5 'forgetting' 头文件..?

ios - 如何正确初始化类

c++ - 关键字 'class' 和 c++ 中的类名之间可以有什么吗?

仅适用于 Windows 上的 Safari 的 CSS 类

c++ - 我可以使用reduce代替for循环吗?

c++ - 如果在内联函数中使用alloca在堆栈上分配了一个变量,那么在内联函数返回后它的引用是否有效?

c++ - const vs非const内联变量

c++ - 关于C++内联函数的几个问题