类定义中定义的成员函数的编译方式是否与C++中其他位置定义的成员函数不同



类定义中定义的成员函数的编译方式是否与C++中其他地方定义的成员函数不同? 例如,考虑以下 foo.h

#pragma once
struct foo {
    void bar() {}
    void buz();
};

还有福.cpp

#include "foo.h"
void foo::buz() {};

如果我们看一下foo.o的符号

$ g++ -c foo.cpp
$ nm -a foo.o
0000000000000000 b .bss
0000000000000000 n .comment
0000000000000000 d .data
0000000000000000 r .eh_frame
0000000000000000 a foo.cpp
0000000000000000 n .note.GNU-stack
0000000000000000 t .text
0000000000000000 T _ZN3foo3buzEv
$ c++filt _ZN3foo3buzEv
foo::buz()

我们看到我们只有一个符号 foo::buz . 现在,假设我们编译了多个都包含foo.h的文件,然后从结果创建一个库。 成员函数是否barbuz区别对待?

是的,有区别。如果在类定义中定义了成员函数,则编译器会尝试使其成为内联函数。对于您的示例,该函数非常简单,可以使其内联。所以编译器已经bar内联,你只看到baz符号。

它是好是坏在很大程度上取决于特定的功能和您的用例。内联函数不需要实际的函数调用,那里有性能改进。但缺点是,如果您在许多地方包含类标头,那么这将增加二进制大小。

另请注意,内联是对编译器的请求。编译器可以自由地忽略请求并将其视为普通方法。

从 9.2.1/1 开始:

成员函数

可以在其类定义中定义,在这种情况下,它是内联成员函数

另一方面,从 9.2.1/2 开始:

内联

成员函数(无论是静态的还是非静态的)也可以在其类定义之外定义,前提是它在类定义中的声明或其在类定义之外的定义将函数声明为内联或constexpr。

问题是:类定义中定义的成员函数的编译方式是否与C++中其他地方定义的成员函数不同?

这主要取决于您如何定义它们,正如您可以从上面的引用中推断出来的那样。
在您的示例中,它们实际上是不同的。

最新更新