2010-11-18 15 views
0

Ich habe eine Klasse Fahrzeug (vehicle.h und vehicle.cpp). Visual Studio gibt mir Fehler, wenn ich die Includes nicht in die Header-Datei einfüge. Warum ist das? In meinen vorherigen 2 Aufgaben habe ich die Includes in die .cpp-Datei eingefügt und hatte keine Probleme. Hier ist, was ich arbeiten wollen, aber nicht ist:C++ wo zu platzieren enthält

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 

Person .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 

Paar von Fehlern zum Beispiel:

Fehler C2061: Syntaxfehler: Bezeichner 'string'

error C2146: Syntaxfehler: fehlt ';' vor Bezeichner

Fehler C2061 'getManufacturer': Syntaxfehler: Bezeichner 'string' Fehler C2535: 'Person :: Person (void)': Member-Funktion bereits definiert oder erklärt
Fehler C2146: Syntaxfehler: fehlen ‚; " vor dem Bezeichner 'get_name'

Fehler C4430: fehlender Typspezifizierer - int wird angenommen. Hinweis: C++ unterstützt nicht default-int

Fehler C4430: fehlende Typangabe - int angenommen. Hinweis: C++ unterstützt nicht default-int

Fehler C2146: Syntaxfehler: fehlende ';' Before identifier 'getDriverLicenseNo'

+1

Was sind die Fehler? –

+0

Können Sie die Fehlermeldungen bitte als Kommentare in den Code eingeben, damit wir wissen, über welche Zeile wir sprechen? –

+0

Sicher, das ist kein Problem, denke ich, aber an diesem Punkt, ohne etwas zu bewegen, habe ich insgesamt 41 Fehler. Gibt es eine Möglichkeit, Visual Studio irgendwie in den Code zu bringen? Die Fehler verschwinden, wenn ich die Includes verschiebe, also bin ich mir ziemlich sicher, dass es das ist. Ich möchte nur verstehen, wie man es richtig macht und nicht jedes Mal mit dem Compiler kämpft. – Pete

Antwort

3

Sie deklarieren eine Instanz von Person in Ihrer Fahrzeugheaderdatei, daher benötigt der Compiler die vollständige Deklaration. Wenn Sie einen Zeiger oder eine Referenz auf eine Person verwenden, können Sie sie einfach mit class Person; weiterleiten.

EDIT: Auch, nehmen Sie diese using namespace std; und Präfix Ihre Variablen mit std::. Es wird in Zukunft eine Menge Ballbeschwerden ersparen.

EDIT2: Sie müssen auch <string> in Ihrer Header-Datei enthalten.

Ok, hier geht es, ich werde versuchen, es nett und einfach zu halten. Wenn der Compiler Ihre Implementierungsdateien (.cpp) verarbeitet, enthält er die Header, die Sie angegeben haben (in diesem Fall wären dies vehicle.h und person.h). Für jede Implementierungsdatei muss der Compiler über jeden einzelnen von Ihnen verwendeten Typ Bescheid wissen, damit er den richtigen Code generieren kann.

Wenn es eine Include-Datei verarbeitet, muss es noch alles wissen. In Ihrer Header-Datei vehicle.h verwenden Sie Person. An dem Punkt, an dem der Compiler das trifft, muss er wissen, wie er eine Person konstruiert. Ihre vehicle.cpp enthält person.h vor vehicle.h so, kein Problem. FÜR vehicle.cpp. Alles andere, das vehicle.h enthält aber person.h nicht enthält, wird Ihnen Compiler-Fehler geben.

Also wann kommst du mit einer Forward-Deklaration durch und benutze einen Zeiger oder eine Referenz?

Zum Deklarieren eines Zeigers oder einer Referenz muss der Compiler nichts über diese Klasse oder Struktur in der Headerdatei mitgeteilt werden. Sie sagen dem Compiler lediglich, dass Sie die Absicht haben, dies zu tun. Vorausgesetzt, dass die Klasse nach vorne thusly erklärt:

class Person; 

Dann sagt der Compiler „okee Dokee, ich nehme das.“ Dann fügen Sie die relevante Datei in Ihre Implementierung ein, der Compiler sieht, was Sie meinen, und alle gehen glücklich von der Bar nach Hause.

Was in Ihrem Fall passiert ist, denke ich, ist, dass die Implementierungsdatei für das Fahrzeug auf dem Papier gut aussieht, aber etwas anderes enthält vehicle.h und es gibt keine Ahnung, was ein Person ist.

Ihre Lösung

Entweder sind person.h in vehicle.h, wenn Sie müssen, andernfalls, dass Konstruktor ändern, um einen Verweis auf Person (und das Mitglied) zu nehmen, und nach vorn Person erklären. Aber wenn ich nicht weiß, was Ihr Programm tut, kann ich nicht sagen, dass auch das Vorübergehen korrekt ist.

Und bitte, entfernen using namespace std; und Ihre string ‚s ändern std::string :)

+1

Er sollte es in der Kopfzeile enthalten. Aber da er "person.h" vor "vehicle.h" enthält, sollte es auch funktionieren. Es ist nicht schön, aber es sollte funktionieren. Die genauen Fehlermeldungen zu kennen wäre also gut. – mmmmmmmm

+0

Können Sie etwas mehr erklären? Ich legte ein Include in die Datei person.h im vehicle.cpp, sollte das nicht genug sein? – Pete

+0

@rstevens, ich habe das verstanden, aber ich frage mich, ob da noch etwas anderes im Spiel ist, das vehicle.h beinhaltet. Für den Compiler zu barf, kann ich nur davon ausgehen, dass es an anderer Stelle enthalten ist. –

1

Wenn Sie ein Objekt einer anderen Klasse in der Klasse setzen, muss der Compiler die gesamte Definition dieser Klasse kennen. Der einfachste Weg, sich an diese Regel zu erinnern, ist zu erkennen, dass Sie die Größe von (Vehicle) nicht wissen können, bis Sie die Größe von (Person) wissen, und auch nicht den Compiler. Zeiger und Verweise auf eine andere Klasse sind in Ordnung, wenn Sie zuerst eine Vorwärtsdeklaration durchführen.

1

Enthält person.h die Zeile #include "vehicle.h"? Kreisförmige Abhängigkeiten sind in C++ schwieriger zu managen als z. Java oder C#. Sie können leicht in eine Situation kommen, wo Sie #include "Person.h" vor #include "Vehicle.h" benötigen, aber Sie benötigen auch #include "Vehicle.h" vor #include "Person.h".

In vielen Fällen müssen Sie dem Compiler sagen "Person ist der Name einer Klasse, aber ich bin noch nicht bereit, Ihnen die Definition zu geben". Dafür können Sie sagen class Person; Dies löst das zirkuläre Referenzproblem.

Auch das Erstellen vieler Kopien eines Objekts Person macht wahrscheinlich keinen Sinn, aber das ist, was Sie mit pass-by-value tun. Es sieht wirklich so aus, als käme man aus einer Java- oder C# -Umgebung, in der Variablen des Klassentyps automatisch (und immer) Referenzen wären. In C++ müssen Sie nach einer Referenz entweder über Person* (ein Zeiger, der so geändert werden kann, dass er auf eine andere Instanz verweist, wie Java und C# Referenzen) oder Person& (eine C++ Referenz, die permanent an eine bestimmte Instanz angehängt ist) fragen.

+0

Meine Person hat keine Angaben zu Vehicle.h. – Pete

Verwandte Themen