2016-08-13 10 views
0

私はコースでVisual Studio 2013を使用してC++を学習していますが、main.cppにインクルードガードに関する問題があります。私はclassまたは#pragma onceのいずれかを使用することはできません。main.cppで複数のヘッダを使用する場合のインクルードガードの方法は?

私だけCoordinatesLineを使用して、私は(LineCoordinatesの両方からコードを取得)main.cpp#include Line.hで使用している場合、これは[OK]を動作しますが、私は(両方とも#include "Line.h"を持っている)RectangleTriangleを追加するとき、それはスロー「既に定義されている」error LNK2005何回か。

何かが欠けていますか?

これは私のコードです:

Coordinates.h

#ifndef Coordinates 
#define Coordinates 
//Code declaration. Other headers have similar declaration 
struct CoordinatesType { double x, y; } coordinates; 
void setCoordinates(double x, double y); 
CoordinatesType getCoordinates(); 
#endif 

Coordinates.cpp

#include "Coordinates.h" 
//Code implementation 

Line.h

#ifndef Line 
#define Line 
#include "Coordinates.h" 
//Code declaration 
#endif 

Line.cpp

#include "Line.h" 
#include <math.h> 
//Code implementation 

Rectangle.h

#ifndef Rectangle 
#define Rectangle 
#include "Line.h" 
//Code declaration 
#endif 

Rectangle.cpp

#include "Rectangle.h" 
//Code implementation 

Triangle.h

#ifndef Triangle 
#define Triangle 
#include "Line.h" 
//Code declaration 
#endif 

main.cppに

#include "Triangle.h" 
#include "Rectangle.h" 
int main(){ 
    //Do stuff here. 
} 

実装コードと宣言コードを追加する必要がある場合はお知らせくださいが、インクルードガードと関係があります。

編集:コーディネートヘッダーにコードを追加して、自分が何をやっているのかを知ることができ、投稿で多くのスペースを消費することを避けることができます。覚えておいて、私はclass Coordinates{}を私の教授の制限のために使用することはできません。

+2

http://stackoverflow.com/help/mcve – melpomene

+0

どのようにクラスの名前が付けられていますか?インクルードガードとしての 'Line'? – Jarod42

+2

あなたの教授は前方宣言の使用を禁止していますか?彼/彼女はあなたに何を教えているのですか? –

答えて

1

このエラーはリンカーエラーであり、コンパイラーエラーではありません。

リンカーでは、ヘッダーガードは何も行いません。

あなたは正常に同じ翻訳単位内の複数の宣言を守っていますが、あなたはプログラム全体にわたる複数の定義を守っていません。

それを防ぐ方法は、そうしないことです。複数のソースファイルにインクルードする場合は、ヘッダーには非インラインで、テンプレート以外の定義はありません。ここで

、あなたはタイプCoordinatesTypeを宣言し、その型のオブジェクトを作成します。

struct CoordinatesType { double x, y; } coordinates; 

はそれをしないでください! CoordinatesTypeのインスタンスをヘッダーではなくソースファイルにのみ作成します。それ以外の場合は、このヘッダーを含むすべてのソースファイル(直接的または間接的)が独自のcoordinatesオブジェクトを取得し、リンカーが名前の衝突について不満を持ちます。

コードは次のようになります。そして、

struct CoordinatesType { double x, y; }; 

、いずれかのオブジェクト&hellipを使用したいでソース・ファイル内のcoordinates。ヘッダー内の宣言にはexternが含まれています。もっと良いアプローチがありますが、このトピックは既に死亡しているので、ここではそれらをすべて列挙しません。さらに、C++の本には説明があります。

しかし、これはヘッダーガードとはまったく関係がないということです。

+1

もちろん、指示に従わずにあなたの[MCVE]を提示していないので、あなたが何を間違えたかを具体的に教えることはできません。 –

+0

今度はコード全体を追加します。 –

+1

@MayerM:誰があなたに "コード全体を追加するように言ったのですか?あなたの[MCVE]をプレゼント!あなたは...一つ持っていますよね? –

-2

Coordinates.hにはインクルードガードがありません。

複数回組み込むと、座標は1回だけ定義されますが、残りのファイルは複数回含まれます。

正しい位置に#endifを置きます。

PS。インクルードガードで使用される識別子は、偶然に他の場所で決して使用されないものでなければなりません。誰かがLineまたはTriangleという名前の変数を使用しようとすると、私は驚くことはありません。そしてそれらを定義すると、予期しないエラーが発生します。 #define LineHeader_Included__のようなものを使用してください。

+0

Eh?インクルードガードがあり、 '#endif'が適切な場所にあります。 –

1

既に指摘したように、あなたの問題はインクルードガードとは関係ありません。

あなたの問題は、この行である:

struct CoordinatesType { double x, y; } coordinates; 

構造体の宣言

struct CoordinatesType { double x, y; }; 

があるため、それは(限り、それは同じであるように、複数の.cppファイルに見えるかもしれないが同じヘッダーファイルを含める場合)、同じ行に変数を定義します(

CoordinatesType coordinates; 

)。定義は一度しか許可されないので、リンカは文句を言う。

あなたが本当にその型のグローバル変数が必要な場合は、(それが必要ではないかもしれないとしてあなたが本当に、1を必要とするかどうかを確認)宣言にあなたのヘッダーを変更します。

struct CoordinatesType { double x, y; }; 
extern CoordinatesType coordinates; 

と定義を使用

CoordinatesType coordinates; 

正確には cpp-fileです。

ラインと座標のみを含むときにエラーが発生しなかったことに注意してください。インクルードガードがで動作し、ヘッダーを1つだけに含めるためです。cppファイル

+0

私はすでにこのすべてを言った。 –

+0

ええ、あなたは数秒であなたの編集で私を打つ;) – Anedar

+0

あなたの助けをありがとう。今私は間違っていたことを理解し、修正しました。ありがとう! –

関連する問題