2010-11-18 5 views
0

입니다. Vehicle (vehicle.h 및 vehicle.cpp) 클래스가 있습니다. Visual Studio에서 헤더 파일 내부에 include를 넣지 않으면 오류가 발생합니다. 왜 이런거야? 이전 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 :

오류 C2061 : 구문 오류 : 예를 들어 오류

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

커플 식별자 '문자열'

에러 C2146 : 구문 오류 : ';'이 없습니다. '인 :: 이용시 (보이드)': 구문 오류 : 식별자 '문자열' 오류 C2535 식별자 'getManufacturer'

오류 C2061 전에 구문 오류 : 이미 정의 또는
오류 C2146 선언 멤버 함수 누락 '; ' 식별자 'get_name'앞에

오류 C4430 : 누락 된 유형 지정자 - int가 사용됩니다. 참고 : C++은 default-int를 지원하지 않습니다.

오류 C4430 : 누락 된 유형 지정자 - int가 사용됩니다. 참고 : C++에서 default-int를 지원하지 않습니다.

오류 C2146 : 구문 오류 : ';'이 (가) 없습니다. before 식별자 'getDriverLicenseNo'

+1

무엇이 오류입니까? –

+0

오류 메시지를 코드의 주석으로 넣어주십시오. 각 줄에서 어떤 줄을 말하고 있는지 알 수 있습니까? –

+0

물론 문제는 아니지만이 시점에서 아무 것도 움직이지 않으면 총 41 개의 오류가 발생합니다. Visual Studio에 코드를 삽입하는 방법이 있습니까? 내가 주변 물품을 옮길 때 오류가 사라져서 그것이 정말 확실하다. 난 그저 제대로하고 컴파일러와 매번 싸우지 않는 방법을 이해하고 싶다. – Pete

답변

3

차량 헤더 파일에 Person의 인스턴스를 선언하므로 컴파일러에 전체 선언이 필요합니다. 사람에 대한 포인터 또는 참조를 사용하는 경우 class Person;과 함께 전달하면됩니다.

편집 : 또한 using namespace std;을 빼고 변수 앞에 std::을 붙입니다. 그것은 미래에 공허함을 많이 줄여 줄 것입니다.

EDIT2 : 또한 헤더 파일에 <string>을 포함해야합니다.

좋아, 여기가 간다. 나는 그것을 멋지고 단순하게 유지하려고 노력할 것이다.

컴파일러가 구현 파일 (.cpp)을 처리 할 때 지정한 헤더 (이 경우 vehicle.hperson.h)가 포함됩니다. 모든 구현 파일에 대해 컴파일러는 올바른 코드를 생성 할 수 있도록 사용하는 모든 단일 유형을 알아야합니다.

포함 파일을 처리 할 때 은 여전히 ​​을 모두 알아야합니다. 따라서 vehicle.h 헤더 파일에 Person을 사용하고 있습니다. 컴파일러가이 점을 깨닫는 순간, 사람을 구성하는 방법을 알아야합니다. vehicle.cppperson.h이 포함되어 있습니다. vehicle.h보다 앞에 있으므로 문제가 없습니다. vehicle.cpp입니다. vehicle.h을 포함하지만 person.h을 포함하지 않는 것은 컴파일러 오류를 줄 것입니다.

그래서 언제 전달 선언과 포인터 또는 참조를 사용할 수 있습니까?

포인터 또는 참조를 선언해도 컴파일러에게 헤더 파일의 해당 클래스 나 구조에 대해 아무 것도 말하지 않아도됩니다. 당신은 컴파일러에게 당신이 그렇게 할 의도가 있다고 말하는 것일뿐입니다. 클래스가 다음과 같이 선언 된 경우 :

class Person; 

그러면 컴파일러에서 "오케이 도케, 내가 취할 것"이라고 말합니다. 그런 다음 구현에 관련 파일을 포함 시키십시오. 컴파일러는 여러분이 의미하는 것을보고 모든 사람들이 바에서 행복하게 집으로 걸어갑니다.

내 생각에, 차량용 구현 파일은 종이로보기 좋지만 다른 것은 vehicle.h을 포함하며 Person이 무엇인지에 대한 단서가 없습니다. 당신이 그렇지 않으면 Person를 선언 앞으로 사람 (및 멤버)에 대한 참조를 취할 것을 생성자를 변경해야하는 경우

귀하의 솔루션

하나는 vehicle.hperson.h을 포함한다. 그러나, 당신의 프로그램이 무엇을하는지 모르는 나는 참조를 지나치다해도 정확하다고 말할 수 없다.

그리고, using namespace std;를 제거하고 당신이 당신의 클래스로 다른 클래스의 객체를 넣을 때 std::string :

+1

헤더에 헤더를 포함해야합니다. 그러나 "vehicle.h"앞에 "person.h"가 포함되어 있기 때문에 제대로 작동해야합니다. 그것은 좋지 않지만 작동해야합니다. 정확한 오류 메시지를 아는 것이 좋습니다. – mmmmmmmm

+0

좀 더 설명해 주시겠습니까? 나는 vehicle.cpp 내 person.h 파일에 include를 넣었습니다. 충분하지 않아야합니까? – Pete

+0

@rstevens, 나는 그것을 잡았다. 그러나 나는 vehicle.h를 포함하는 놀고있는 다른 것이 있는지 궁금하다. 컴파일러가 barf에 대해서, 나는 그것이 다른 곳에 포함되는 것으로 가정 할 수있다. –

1

string 년대를 변경하십시오, 컴파일러는 그 클래스의 전체 정의를 알 필요가있다. 이 규칙을 기억하는 가장 쉬운 방법은 sizeof (Person)을 알기 전까지 sizeof (Vehicle)를 알 수없고 컴파일러도 알 수 없다는 것을 깨닫는 것입니다. 전달 선언을 먼저 수행하면 포인터와 다른 클래스에 대한 참조는 정상입니다.

1

person.h에는 #include "vehicle.h" 행이 있습니까? 순환 종속성은 C++에서 관리하기가 더 어렵습니다. 자바 또는 C#. #include "Vehicle.h" 전에 #include "Person.h"이 필요한 상황에 쉽게 도달 할 수 있지만 #include "Person.h" 전에 #include "Vehicle.h"도 필요합니다.

많은 경우 컴파일러에게 "Person은 클래스의 이름이지만, 아직 정의를 제공 할 준비가되지 않았습니다."라고 말해야합니다. 이를 위해 class Person;라고 말할 수 있습니다. 순환 참조 문제를 해결합니다.

또한 Person 개체의 복사본을 많이 만드는 것은 의미가 없지만 실제로는 패스 바이 값을 사용하여 작업하고 있습니다. 클래스 유형의 변수가 자동으로 (그리고 항상) 참조 인 자바 또는 C# 환경에서 온 것처럼 보입니다. C++에서 Person* (포인터는 Java 및 C# 참조와 같은 다른 인스턴스를 가리 키도록 변경할 수 있음) 또는 Person& (특정 인스턴스에 영구적으로 연결된 C++ 참조)을 통해 참조를 요청해야합니다.

+0

내 개인은 Vehicle.h을 (를) 검색해보세요. – Pete

관련 문제