1

インライン化の方法について質問があります。衝突モデル用に開発されたライブラリを使用しています。グラフィックインターフェイスを担当する1つのヘッダーファイルには、関数の宣言と実装が含まれていますが、関数はインライン化されていません。したがって、これらの機能を複数の変換単位に含めることはできません。実例として、ここに私が実例のために設計したダミーコードがあります:

LivingBeing.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

Forest.h

#ifndef FOREST_H
#define FOREST_H

#include "LivingBeing.h"

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

#endif

Forest.cpp

#include "Forest.h"

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

Main.cpp

#include "Forest.h"

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

このコードは、コンストラクターLivingBeingとメソッドbreathの前に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::LivingBeingおよびLivingBeing::breathe) を定義しています。つまり、そのヘッダーを含む各翻訳単位に定義が存在します。これは One Definition Rule (ODR) に違反するため、リンク エラーが発生します。

次の 3 つのオプションがあります。

  • 関数定義をソース ファイルに移動して、一度だけ定義されるようにします。また
  • inline複数の同一の定義を許可するように宣言します。また
  • 定義をクラス定義内に移動すると、暗黙的にそれらが になりますinline

メソッドのインライン化の欠点は何ですか?

  • コンパイル時間と実行可能ファイルのサイズが増加する可能性があります。ただし、顕著な違いがあるかどうかを確認するには、測定する必要があります。
  • 安定性の低い API - インライン関数が変更されるたびに、クライアント コードを再コンパイルする必要があります。
  • たとえば、異なる翻訳単位で異なる展開を持つ可能性のあるマクロが関数に含まれている場合など、誤って ODR を壊す可能性があります。
于 2013-02-19T11:05:24.263 に答える
0

メソッドが「ソース」ファイル (.c/.cpp) で定義されているからといって、インライン化されないわけではありません... リンク時の操作でその最適化が実行される場合があります。逆に、メソッドがヘッダー ファイルでインラインとして宣言および実装されているからといって、それがインライン化されるとは限りません。一般に、メソッドが非常に単純な場合は、ヘッダー ファイルでメソッドを定義しますint getWidth() const { return width; }MyObj* getNext() { return internal_itor ? internal_itor->next : 0; }

于 2013-02-19T12:08:25.573 に答える