我已经了解了通常最好不要在头文件中定义任何内容,因为冗余副本是针对包含头文件的每个其他文件进行的。然而,在静态内联方法的情况下,似乎我必须在现场定义它(至少Visual Studio 2010不允许我这样做)。因此,如果我在头文件中编写接口,我就无法定义类定义的静态内联方法或.cpp文件。
那么,我是否应该费心去使用静态内联方法呢?还有一个相关问题:我是否应该在头文件中定义任何方法或变量(常量怎么样)?
无论如何,奇怪的是,我的C ++书籍中没有详细介绍过这些内容。
编辑:我读过有关静态内联方法的类似问题,但似乎没有一个直接解决这个问题。
答案 0 :(得分:38)
如何在头文件中添加函数定义?
这可以通过3种可能的方式实现:
inline
或static
或这样做的正确方法是什么?
#1
即:在不破坏 一个定义规则 的情况下,将函数inline
标记为正确的方法。
其他两个appraoches有什么问题?
同时#2
& #3
每个翻译单元将包含它自己的函数版本,程序将包含函数的几个不同版本,从而导致生成的二进制文件的大小增加。
即:对于static
函数fun()
,&fun
在每个翻译单元中都会有所不同,程序将包含N
个不同版本的函数。
此外,如果函数包含静态局部变量,那么将有N
个不同的静态局部变量,每个函数实例一个。
第一种方法如何避免此问题?
inline
函数具有外部链接
标记函数inline
时,该函数将在所有翻译单元中具有相同的地址。此外,在内联函数体内定义的静态局部变量和字符串文字被视为跨翻译单元的同一对象
简而言之,内联函数将在所有翻译单元中具有相同的地址。
标题中
static inline
函数定义的处理方式是什么?
static
关键字强制该函数具有内部链接
定义为内联的每个函数实例都被视为一个单独的函数,每个实例都有自己的静态本地和字符串文字的副本。因此,这与#2
类似。
注意:强>
标准要求inline
的所有定义在用户程序中起作用您必须在使用或调用该函数的所有翻译单元中具有完全相同的定义。
相关的Standerdese参考文献:
C ++ 03标准
3.2一个定义规则:
第3段:
每个程序应该只包含该程序中使用的每个非内联函数或对象的一个定义;无需诊断。该定义可以在程序中明确显示,可以在标准或用户定义的库中找到,或者(在适当的时候)隐式定义(见12.1,12.4和12.8)。 应在每个使用它的翻译单元中定义内联函数。
7.1.2函数说明符
第4段:
内联函数应在每个使用它的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。 [注意:在定义出现在翻译单元之前,可能会遇到对内联函数的调用。 ]如果在一个翻译单元中内联声明具有外部链接的功能,则应在其出现的所有翻译单元中内联声明;无需诊断。 具有外部链接的内联函数在所有翻译单元中应具有相同的地址。 anterntern内联函数中的静态局部变量始终引用同一对象。 extern内联函数中的字符串文字是不同翻译单元中的相同对象。
答案 1 :(得分:6)
(1)我无法在类的外侧定义静态内联方法 定义或.cpp文件。
您可以在头文件中定义类外的static inline
方法。 Demo。您无法在.cpp文件中定义它们。
(2)我是否应该在所有
中使用静态内联方法
我想说,可以很容易地避免它们。如果您需要在头文件中查看正文以用于您自己的目的,那么只需将它们设为inline
。
(3)我是否应该在头文件中定义任何方法或变量 (常数怎么样)
static const
数据
类型。static
个方法
static inline
方法可以在类体内或外部定义
头文件中的类主体static
数据成员必须在单个.cpp
文件中定义,以符合一个定义规则