0

次のような構造を作成する必要があります。

// file main.h:
#pragma once

#ifndef _MAIN_H
#define _MAIN_H

#include <iostream>

#include "first.h"
#include "second.h"

#endif
// -----------------

// file first.h:
#pragma once

#ifndef _FIRST_H
#define _FIRST_H

#include "main.h" // because of using SomeFunction() in first.cpp

int SomeVar; // used in first.cpp

#endif
// -----------------

// file second.h:
#pragma once

#ifndef _SECOND_H
#define _SECOND_H

#include "main.h" // because of using SomeVar in second.cpp

int SomeFunction(); // implemented in second.cpp

#endif
// -----------------

論理的には、main.h最初にコンパイルされる場合、この各ヘッダーは1回だけ含まれ、すべての変数/関数は正常に定義されます。

たとえば、この構成は、オプション「preinclude file」(プリコンパイルされていない)で設定されている場合、IARC++コンパイラで通常コンパイルされますmain.h

ただし、Visual Studio 2010では、同じ構造により次のようなリンカーエラーが発生します。

1>second.obj : error LNK2005: "int SomeVar" (?SomeVar@@3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction@@3HA) already defined in first.obj

アルファベット順にファイルを入れているからだと思います。どうやらプラグマガードと定義ガードはリンカーによって無視されます。

エラーは、追加のヘッダーと変数の定義によって修正できますexternalが、これは困難で間違った方法です。

質問は:私は何をすべきですか?

4

2 に答える 2

2
int SomeVar; // used in first.cpp

変数をヘッダーで定義しないでください。それらは次のように宣言する必要がありますextern

extern int SomeVar; // used in first.cpp

次に、実際に「first.cpp」で。を使用してそれらを定義できますint SomeVar;


また、「first.h」に「main.h」を含める必要はありません。そのヘッダーの定義がそれらのファイルの内容を絶対に必要とする場合にのみ、ヘッダーにファイルを含める必要があります。「first.h」の定義は「main.h」には何も必要ありません。したがって、それを含めるべきではありません。

「first.cpp」に「second.h」の何かを含める必要がある場合、それを含めるのは「first.cpp」の責任です。

于 2011-07-15T11:12:20.423 に答える
1

ヘッダーファイルで、externキーワードを次のように使用します。

//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere

次に、.cppファイルでそれを定義して使用します。

//first.cpp
int SomeVar; //definition is here

についてはSomeFunction、ヘッダーファイル自体を定義しましたか?再確認してください。:-)

于 2011-07-15T11:11:04.773 に答える