23

我已经了解了通常最好不要在头文件中定义任何内容,因为包含头文件的每个其他文件都会生成冗余副本。但是,在静态内联方法的情况下,似乎我必须在现场定义它(至少 Visual Studio 2010 不允许我这样做)。因此,如果我在头文件中编写接口,则无法在类定义之外或在 .cpp 文件中定义静态内联方法。

那么,我应该费心使用静态内联方法吗?还有一个相关的问题:我是否应该在头文件中定义任何方法或变量(常量呢)?

无论如何,奇怪的是,我的 C++ 书籍中并没有详细介绍它。

编辑:我通读了关于静态内联方法的类似问题,但似乎没有一个直接解决这个问题。

4

2 回答 2

44

如何在头文件中添加函数定义?

这可以通过 3 种可能的方式实现:

  1. 标记功能inline
  2. 制作函数static
  3. 将函数放在匿名命名空间中。

这样做的正确方法是什么?

#1即:标记函数inline是正确的方法,而不会破坏One Definition Rule

其他两种方法有什么问题?

在这两个#2#3每个翻译单元中都将包含它自己的函数版本,并且程序将包含函数的几个不同版本,从而导致生成的二进制文件的大小增加。
即:对于一个static函数fun()&fun在每个翻译单元中会有所不同,程序会包含N不同版本的函数。
此外,如果函数包含静态局部变量,那么将有N不同的静态局部变量,每个函数实例一个。

第一种方法如何避免这个问题?

inline函数具有外部链接。
当您标记一个函数时inline,该函数将在所有翻译单元中具有相同的地址。此外,在内联函数体内定义的静态局部变量和字符串文字在翻译单元中被视为相同的对象。
简而言之,内联函数将在所有翻译单元中具有相同的地址。

头文件中的static inline函数定义是怎么回事?

static关键字强制函数具有内部链接。
每个定义为 inline 的函数实例都被视为一个单独的函数,并且每个实例都有自己的静态局部变量和字符串文字的副本。因此,这将类似于#2

注意:
该标准要求inline用户程序中的所有函数定义必须在使用或调用该函数的所有翻译单元中具有完全相同的定义。


相关标准参考:

C++03 标准

3.2 一个定义规则:
第 3 段:

每个程序都应包含该程序中使用的每个非内联函数或对象的一个​​定义;无需诊断。定义可以显式出现在程序中,可以在标准或用户定义库中找到,或者(在适当时)隐式定义(参见 12.1、12.4 和 12.8)。内联函数应在使用它的每个翻译单元中定义。

7.1.2 函数说明符
第 4 段:

内联函数应在使用它的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。[注意:在其定义出现在翻译单元之前,可能会遇到对内联函数的调用。] 如果具有外部链接的函数在一个翻译单元中声明为内联,则应在其出现的所有翻译单元中声明为内联;不需要诊断。具有外部链接的内联函数在所有翻译单元中应具有相同的地址。anextern 内联函数中的静态局部变量始终引用同一个对象。外部内联函数中的字符串文字是不同翻译单元中的相同对象。

于 2012-06-01T09:02:21.793 回答
7

(1) 我无法在类定义之外或在 .cpp 文件中定义静态内联方法。

static inline您可以在头文件中的类之外定义方法。演示。您不能在 .cpp 文件中定义它们。

(2) 我应该费心使用静态内联方法吗

我会说,它们很容易避免。如果您出于自己的目的需要查看头文件中的正文,则只需将它们设为inline.

(3)我是否应该在头文件中定义任何方法或变量(常量呢)

  1. 在类体内,您可以定义static const整型数据。
  2. static方法可以在类体内定义
  3. static inline方法可以定义在类主体内部或头文件中的类主体外部
  4. static数据成员必须在单个.cpp文件中定义以遵守一个定义规则
于 2012-06-01T09:02:30.413 回答