0

私は、「bh」などutil.hで使用される関数を含み、互いに定義されたいくつかのクラスにアクセスするために互いにインクルードします。a.ha.hb.h

//util.h

#ifndef _UTIL_H_
#define _UTIL_H_

#include <iostream>

void foo()
{
    std::cout << "foo\n";
}

#endif

//a.h, it has a a.cpp
#ifndef _A_H_
#define _A_H_

#include "util.h"
#include "b.h"

//some classes' definition

#endif

//b.h, it has a b.cpp
#ifndef _B_H_
#define _B_H_

#include "util.h"
#include "a.h"

//some classes' definition

#endif

私の問題は、 のmultiple definitionエラーが発生したことですfoo。どのように?

a.h問題は、 includesutil.hb.h、 and b.hincludesutil.hがもう一度あることだと思ったので、複数の def エラーが発生しました。しかし、私はガードutil.hを書いたので、それは意味をなさないようです.#ifndef/#define

誰でも私を助けてくれます、ありがとう。

4

1 に答える 1

6

あなたの問題は、内部で単に宣言するのではなく、定義することによって引き起こされます fooutils.h

この例では、次のものがあると仮定します。

a.cpp

#include "a.h"

b.cpp

#include "b.h"

main.cpp

#include "a.h"
#include "b.h"
#include "utils.h"


int main(){
    foo();
    return 0;
}

前処理後、コンパイル前のファイルは次のようになります (これは単純化したものですが、おわかりいただけると思います)。

a.cpp

void foo()
{
    std::cout << "foo\n";
}

b.cpp

void foo()
{
    std::cout << "foo\n";
}

main.cpp

void foo()
{
    std::cout << "foo\n";
}

int main(){
    foo();
    return 0;
}

コンパイルすると、3 つの定義が得られfooます (それらはすべて同一ですが、これは無関係です)。コンパイル後、リンカーは特定の呼び出しに対してどの定義を選択するかを知る方法がないためfoo、エラーが生成されます。

fooヘッダーで定義する代わりに、で定義し、utils.cpp宣言のみを入れます。utils.h

utils.h

#ifndef _UTIL_H_
#define _UTIL_H_

void foo();

#endif

または、代わりにorとして宣言fooします。staticinline

utils.h

#ifndef _UTIL_H_
#define _UTIL_H_

static void foo()
{
    std::cout << "foo\n";
}

/* OR */

inline void foo()
{
    std::cout << "foo\n";
}


#endif

これは、関数をインライン化したい場合にのみ行う必要があることです。この場合、コンパイラは、基本的にコンパイル時のマクロになるため、使用されるすべての翻訳単位で関数の定義を必要とします

于 2012-08-09T04:02:20.057 に答える