次のような構造を作成する必要があります。
// 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
が、これは困難で間違った方法です。
質問は:私は何をすべきですか?