2010-11-18 6 views
0

私はクラスVehicle(vehicle.hとvehicle.cpp)を持っています。ヘッダーファイルのインクルードを入れないと、Visual Studioでエラーが表示されます。どうしてこれなの?前の2つの課題では、インクルードファイルを.cppファイルに入れて問題はありませんでした。ここで私が仕事をしたいものですが、ありません:C++どこに入れるか

vehicle.h:

#ifndef VEHICLE_H 
#define VEHICLE_H 

using namespace std; 
class Vehicle 
{ 
public: 
    Vehicle(); 
    Vehicle(string mfr, int cylinders, Person owner); 
    string getManufacturer(); 
    int getNumOfCylinders(); 
    Person getOwner(); 
private: 
    string manufacturer; 
    int numOfCylinders; 
    Person owner; 
}; 
#endif 

vehicle.cpp:

#include <iostream> 
#include <string> 
using namespace std; 
#include "person.h" 
#include "vehicle.h" 

Vehicle::Vehicle() 
{ 
    //Initialize with defaults 
} 
Vehicle::Vehicle(string mfr, int cylinders, Person owner) 
{ 
    //Initialize with parameters 
} 
string Vehicle::getManufacturer() 
{ 
    return manufacturer; 
} 
int Vehicle::getNumOfCylinders() 
{ 
    return numOfCylinders; 
} 
Person Vehicle::getOwner() 
{ 
    return owner; 
} 

person.h:

#ifndef PERSON_H 
#define PERSON_H 
class Person { 
    public: 
     //default constructor 
     Person(); 
     //constructor with two parameters 
     Person(string the_name, string no); 
     //accessor member functions 
     string get_name() const; 
     string getDriverLicenseNo() const; 
     //overloaded equal operator 
     bool operator==(const Person& p); 

     //overloaded extraction operator 
     friend istream& operator >> (istream& in, Person& p); 
     //overloaded insertion operator 
     friend ostream& operator <<(ostream& out, Person& p); 
    private: 
     string name; 
     string drivingLicenseNo; 
}; 
#endif 

人.cpp:

#include <iostream> 
#include <string> 
using namespace std; 
#include "person.h" 


//default constructor 
Person::Person(){} 
//constructor with two parameters 
Person::Person(string the_name, string no){} 
//accessor member functions 
string Person::get_name() const 
{ 
    return name; 
} 
string Person::getDriverLicenseNo() const 
{ 
    return drivingLicenseNo; 
} 
//overloaded equal operator 
bool Person::operator==(const Person& p) 
{ 
    return false; 
} 

//overloaded extraction operator 
istream& operator >> (istream& in, Person& p) 
{ 
    return in; 
} 
//overloaded insertion operator 
ostream& operator <<(ostream& out, Person& p) 
{ 
    return out; 
} 

truck.h:

#include "vehicle.h" 
class Truck: public Vehicle 
{ 

}; 

truck.cpp:例えばエラーの

#include "person.h" 
#include "vehicle.h" 
//implement truck here 

カップル:

エラーC2061:構文エラー:識別子 '列'

エラーC2146:構文エラー: ';'がありません。識別子の前に「getManufacturer」

エラーC2061:構文エラー:識別子「string」は エラーC2535:「人::人(無効)」:構文エラー:メンバ関数がすでに
エラーC2146定義または宣言した「行方不明に。 '識別子 'get_name'の前に

エラーC4430:欠落型指定子 - intが仮定されています。注:C++はdefault-intをサポートしていません

エラーC4430:型指定子がない - 想定されています。注:C++はdefault-intをサポートしていません

エラーC2146:構文エラー: ';'がありません。 before識別子 'getDriverLicenseNo'

+1

エラーは何ですか? –

+0

エラーメッセージをコード内のコメントとして入力して、それぞれの行がどのようなものかを知ることができますか? –

+0

確かに、それは私が推測する問題ではありませんが、この時点では何も動かさずに、合計41のエラーがあります。ビジュアルスタジオにコードを挿入する方法はありますか?インクルードを動かすとエラーが消えてしまいます。私はちょうどそれを正しく行う方法を理解し、毎回コンパイラと戦わないようにしたい。 – Pete

答えて

3

Personのインスタンスを車両ヘッダファイルに宣言しているため、コンパイラは完全な宣言を必要とします。人へのポインタや参照を使用していた場合は、単にclass Person;で宣言してください。

編集:また、using namespace std;を取り出し、変数にstd::という接頭辞を付けます。それは将来、多くの苦痛を節約します。

EDIT2:ヘッダファイルに<string>も含める必要があります。

ここでは、私はそれを素敵でシンプルに保つつもりです。

コンパイラが実装ファイル(.cpp)を処理すると、指定したヘッダー(この場合はvehicle.hperson.h)が含まれます。すべての実装ファイルについて、コンパイラは正しいコードを生成できるように、使用するすべての単一の型について知る必要があります。

インクルードファイルを処理するとき、はまだすべてを知る必要があります。したがって、vehicle.hヘッダーファイルでは、Personを使用しています。コンパイラがそれに当たる時点で、人を構築する方法を知る必要があります。 vehicle.cppにはperson.hが含まれています。vehicle.hの前に問題ありません。 の場合はvehicle.cppです。 vehicle.hが含まれていますが、person.hは含まれていないものは、コンパイラエラーが発生します。

したがって、前方宣言とポインタまたは参照をいつ利用できますか?

ポインタまたは参照の宣言では、ヘッダファイル内のそのクラスまたは構造体についてコンパイラに何も通知する必要はありません。コンパイラにあなたがそうするつもりであると伝えるだけです。クラスが前方thusly宣言されていること提供:

class Person; 

を次にコンパイラが言う「okee dokeeを、私はそれを取りますよ。」次に、関連するファイルを実装に含めると、コンパイラはあなたが何を意味しているかを見て、みんながバーから幸せに歩いていくのを見ます。

私はあなたのケースで何が起こったのかというと、車の実装ファイルは紙の上で見栄えが良いと思われますが、それ以外にはvehicle.hが含まれていて、Personが何であるかについての手掛かりはありません。あなたは、そうでない場合Personを宣言前方人(およびメンバー)への参照を取るために、そのコンストラクタを変更し、必要がある場合

あなたのソリューション

のどちらかがvehicle.hperson.hが含まれます。しかし、あなたのプログラムが何をしているのか分からず、私は、参照渡しが正しいと言うことはできません。

そして、using namespace std;を削除して、あなたのクラスに別のクラスのオブジェクトを置くときstd::string :)

+1

ヘッダーに含める必要があります。しかし、 "vehicle.h"の前に "person.h"が含まれているので、それもうまくいくはずです。それはいいではありませんが、それは動作するはずです。正確なエラーメッセージがわかっていると分かります。 – mmmmmmmm

+0

もう少し説明できますか?私はvehicle.cpp内のperson.hファイルへのインクルードを入れました。十分ではありませんか? – Pete

+0

@rstevens、私はそれをキャッチしましたが、それ以外の何かがvehicle.hを含む他のものがあるのだろうかと思います。コンパイラがbarfにするために、私はそれが他の場所に含まれていると仮定することしかできません。 –

1

にごstring年代を変更してください、コンパイラはそのクラスの定義全体を知る必要があります。このルールを覚えるのが最も簡単な方法は、sizeof(人)が分かるまでsizeof(Vehicle)を知ることができないことを理解することです。最初に前方宣言を行うと、ポインタと別のクラスへの参照はOKです。

1

person.hには、#include "vehicle.h"という行が含まれていますか?円の依存関係は、C++では管理するのが難しい。 JavaまたはC#。 #include "Vehicle.h"の前に#include "Person.h"が必要な状況に簡単に入ることができますが、#include "Vehicle.h"の前に#include "Person.h"も必要です。

多くの場合、コンパイラに「Personはクラスの名前ですが、まだ定義を与える準備ができていません」と伝える必要があります。そのためには、class Person;と言うことができます。これは、循環参照問題を解明します。

また、Personオブジェクトのコピーをたくさん作成するのはおそらく意味をなさないでしょうが、これは値渡しで行うことです。実際には、クラス型の変数が自動的に(そして常に)参照されるJavaまたはC#環境から来ているようです。 C++では、Person*(ポインタは、JavaとC#の参照のような別のインスタンスを指すように変更できます)またはPerson&(特定のインスタンスに永続的に接続されたC++参照)のいずれかで参照を要求する必要があります。

+0

私の人はVehicle.hを持っていません。 – Pete

関連する問題