我有一个 Vehicle 类(vehicle.h 和 vehicle.cpp)。如果我不将 include 放在头文件中,Visual Studio 会给我错误。为什么是这样?在我之前的 2 个作业中,我将 include 放在 .cpp 文件中并且没有任何问题。这是我想要但不是的工作:
车辆.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
车辆.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;
}
人.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;
}
卡车.h:
#include "vehicle.h"
class Truck: public Vehicle
{
};
卡车.cpp:
#include "person.h"
#include "vehicle.h"
//implement truck here
例如几个错误:
错误 C2061:语法错误:标识符“字符串”
错误 C2146:语法错误:缺少“;”在标识符“getManufacturer”之前
错误 C2061:语法错误:标识符“字符串”
错误 C2535:“Person::Person(void)”:成员函数已定义或声明
错误 C2146:语法错误:缺少“;”在标识符 'get_name' 之前
错误 C4430:缺少类型说明符 - 假定为 int。注意:C++不支持default-int
错误 C4430:缺少类型说明符 - 假定为 int。注意:C++不支持default-int
错误 C2146:语法错误:缺少“;”在标识符“getDriverLicenseNo”之前
最佳答案
您正在声明 Person
的一个实例在您的车辆头文件中,因此编译器需要完整的声明。如果你正在使用一个指针或对一个人的引用,你可以简单地用 class Person;
转发声明它。 .
编辑:另外,取出 using namespace std;
并在变量前加上 std::
.它会在未来节省很多球痛。
EDIT2:您还需要包括 <string>
在你的头文件中。
好的,开始吧,我会尽量保持它的美观和简单。
当您的编译器处理您的实现文件 (.cpp) 时,它会包含您指定的 header (在本例中为 vehicle.h
和 person.h
)。对于每个实现文件,编译器需要了解您使用的每种类型,以便它可以生成正确的代码。
当它处理一个包含文件时,它仍然需要知道一切。所以在你的vehicle.h
头文件,您正在使用 Person
.当编译器遇到这个问题时,它需要知道如何构造 person。你的vehicle.cpp
包括 person.h
之前 vehicle.h
所以,没问题。 对于vehicle.cpp
强>。任何其他包括 vehicle.h
的内容但不包括 person.h
, 会给你编译器错误。
那么什么时候可以摆脱前向声明并使用指针或引用?
声明指针或引用不需要在头文件中告诉编译器有关该类或结构的任何信息。您只是告诉编译器您打算这样做。前提是该类是这样声明的:
class Person;
然后编译器说“okee dokee,我接受它。”然后您将相关文件包含在您的实现中,编译器明白您的意思,然后每个人都高兴地从酒吧走回家。
我认为,在您的案例中,车辆的实现文件在纸面上看起来不错,但其他内容包括 vehicle.h
并且不知道什么是Person
是。
您的解决方案
要么包括person.h
在 vehicle.h
如果必须,否则更改该构造函数以引用人(和成员),并转发声明 Person
.但是,由于不知道您的程序在做什么,我不能说即使是按引用传递也是正确的。
请删除using namespace std;
并更改您的 string
到std::string
:)
关于C++ 放置位置包括,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4219782/