【问题标题】:Are member functions defined in a class definition compiled differently than member functions defined elsewhere in C++?类定义中定义的成员函数是否与 C++ 中其他地方定义的成员函数不同?
【发布时间】:2016-06-05 05:48:35
【问题描述】:

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

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

和 foo.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 的处理方式是否不同?

【问题讨论】:

  • 尝试再次编译相同的东西,但使用内联成员函数。

标签: c++


【解决方案1】:

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

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

还要注意,inline 是对编译器的请求。编译器可以随意忽略该请求并将其视为普通方法。

【讨论】:

  • 内联成员函数也可能导致不必要的重新编译。任何包含头文件的内容都需要在任何编辑时重新编译,而如果更改​​位于 C++ 源文件中,则只有该文件需要重新编译(并且使用它的所有内容都重新链接,这并不昂贵)。跨度>
【解决方案2】:

来自9.2.1/1

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

另一边,来自9.2.1/2

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

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

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

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多