类内的内联函数成员
Posted
技术标签:
【中文标题】类内的内联函数成员【英文标题】:inline function members inside a class 【发布时间】:2012-03-11 08:18:42 【问题描述】:我知道,当函数定义对于性能而言很小并且可以节省编译时间时,将函数(普通函数而不是类中的方法)声明为内联是一种很好的做法。但是类中的内联方法怎么样 我不明白类中内联方法的概念?如何定义它们以及它们是如何工作的。
【问题讨论】:
“当函数定义对性能来说很小并且可以节省编译时间时,这是一个很好的做法” - 你从哪里读到的? @OliCharlesworth :我的意思是如果函数包含一个或两个语句,那么将这个函数声明为内联将节省编译对定义所做的跳转时间,特别是如果这个函数被调用了很多次. 请记住,由于编译器会在每个调用站点为内联函数生成代码,因此您可能没有帮助您的编译时间。过多的内联会降低编译时间并增加可执行文件的大小。 只是一个澄清。内联声明不会节省编译时间。它以牺牲大小为代价节省了代码执行期间的时间。假设您放入函数中的代码需要 500 字节。如果没有内联,该函数使用 500 字节,但 cpu 将“浪费”时间用于函数的“跳转”。使用内联代码,每次调用将使用 500 字节,但速度更快。基本上,内联建议编译器更喜欢速度而不是大小。在执行时间很关键(即中断)的嵌入式环境中非常有用 以下链接是来自 IBM 的简短但非常好的解释。 ibm.com/support/knowledgecenter/en/SSLTBW_2.3.0/… 【参考方案1】:在类中将函数/过程指定为inline
是在向编译器暗示,与其创建代码来调用函数和传递参数,不如将函数的内容放在调用点。
当无需传递参数即可更高效地执行函数时,它可以提高编译后的二进制文件的性能。这也可能会损害性能,因为在每个调用位置重复函数中的代码可能会导致膨胀,从而降低您的代码在更快的高速缓存中找到的可能性。
【讨论】:
【参考方案2】:但是类中的内联方法呢?
内联函数的两种语法(使用显式 inline
并在类定义中定义成员函数)仅提供有关编译器内联的提示。从性能的角度来看,它们是相等的。
如果在类声明中定义一个成员函数,后者的可读性应该是你主要关心的:用多行实现细节乱扔类接口真的很痛苦。因此,如果您的成员函数不止一个语句,请避免这样做:return stuff
或简单转发应该可以,但通常不会超过这个。
class MyClass
public:
int f() const return m_i;
int g() const;
private:
int m_i;
;
inline int MyClass::g() const
return m_i;
// both member-functions behave equally (except for naming)
【讨论】:
是声明,g()的定义必须和main()函数在同一个文件中。或者可以只写函数 g() 的声明和另一个文件中的定义。 定义可以放在单独的文件中,但它需要与调用@的代码在同一个翻译单元中987654324@。这实际上意味着该定义应包含在包含该调用的源文件中。 这是否意味着类定义中的函数定义被自动视为内联?如果不是这样,为什么可以在不同的文件中多次定义同一个类(具有相同的函数)而不破坏函数的单一定义规则? @Hal 是的,确实如此 '(命名除外)'是编译后函数的命名吗?【参考方案3】:有两个选项可以提供给编译器来内联类函数:
(1)在类的声明中定义一个函数(在头文件中)
class Human
public:
Human(const char* name);
Human();
// is implicit inline
void lookAt(const char* name) const
std::cout << "I'm looking at " << name << std::endl;
private:
char _name[30];
;
(2)在函数定义中显式使用inline关键字(在头文件中)
// is explicit inline
inline void lookAt(const char* name) const
std::cout << "I'm looking at " << name << std::endl;
【讨论】:
您不能将inline
方法放在.cpp 文件中。它仍然必须放在标题中。
是的,你是对的。如果我将内联方法定义放在 .cpp 文件中,我将从链接器收到“未解决的外部”错误。因此,无论是显式还是隐式,内联函数都必须在标题中。
不过有一个例外:private 内联函数只能在 cpp 文件中使用可以在那里定义...以上是关于类内的内联函数成员的主要内容,如果未能解决你的问题,请参考以下文章