1

我有一个关于内联方法的问题。我正在使用为碰撞模型开发的库。一个负责图形界面的头文件包含函数的声明和实现,但函数没有内联。因此,不可能将这些功能包含在几个翻译单元中。作为说明,这里是我为说明而设计的虚拟代码:

活人.h

#ifndef LIVINGBEING_H
#define LIVINGBEING_H

class LivingBeing
{
public:
    LivingBeing(double _size);
    void breathe();
private:
    double size;
};
//////////////

LivingBeing::LivingBeing(double _size)
{
    size = _size;
}
void LivingBeing::breathe()
{
    // do something
}
#endif

森林.h

#ifndef FOREST_H
#define FOREST_H

#include "LivingBeing.h"

class Forest
{
public:
    Forest(int _numberLivingBeings);
private:
    int numberLivingBeings;
};

#endif

森林.cpp

#include "Forest.h"

Forest::Forest(int _numberLivingBeings)
{
    numberLivingBeings = _numberLivingBeings;
            // Call LivingBeing constructor, methods etc...
}

主文件

#include "Forest.h"

int main()
{
    Forest forest = Forest(10);
    return 0;
}

除非我在构造函数 LivingBeing 和方法呼吸前添加 inline 关键字,否则此代码不会编译。错误信息是:

1>main_test.obj : error LNK2005: "public: __thiscall LivingBeing::LivingBeing(double)" (??0LivingBeing@@QAE@N@Z) already defined in Forest.obj
1>main_test.obj : error LNK2005: "public: void __thiscall LivingBeing::breathe(void)" (?breathe@LivingBeing@@QAEXXZ) already defined in Forest.obj
1>C:\Users\******\Documents\Visual Studio 2010\Projects\TutorialChronoEngine\Debug\Test_3.exe : fatal error LNK1169: one or more multiply defined symbols found

我的问题是:内联方法的缺点是什么?我使用的真实库非常大,我想从特定文件(在我的示例中为 LivingBeing.h)内联方法,以便可以在多个 .cpp 文件中使用这些方法。更改源文件有什么风险?

非常感谢

4

2 回答 2

4

您在标题中定义函数 (LivingBeing::LivingBeingLivingBeing::breathe),这意味着在包含该标题的每个翻译单元中都会有一个定义。这打破了单一定义规则 (ODR),因此出现了链接错误。

你有三个选择:

  • 将函数定义移动到源文件中,以便它们只定义一次;或者
  • 声明它们inline允许多个相同的定义;或者
  • 在类定义中移动定义,这隐含地使它们inline.

what is the drawbacks of inlining methods ?

  • Possibly increased compilation time and executable size; but you'd need to measure to see whether there's any noticable difference.
  • A less stable API - client code will need recompiling whenever any inline function changes.
  • The possibility of accidentally breaking the ODR, for example if a function contains macros which might have different expansions in different translation units.
于 2013-02-19T11:05:24.263 回答
0

Just because a method is defined in a "source" file (.c/.cpp) doesn't mean it won't be inlined... link-time operations may perform that optimization. Oppositely, just because a method is declared and implemented as inline in a header file doesn't mean it will be inlined. In general, I define methods in a header file if they are very simple, e.g. int getWidth() const { return width; }, or MyObj* getNext() { return internal_itor ? internal_itor->next : 0; }

于 2013-02-19T12:08:25.573 回答