C++放置位置包括
我有一个车辆类(vehicle.h 和vehicle.cpp)。如果我没有将包含内容放入头文件中,Visual Studio 就会出现错误。这是为什么呢?在我之前的 2 个作业中,我将包含内容放入 .cpp 文件中,没有出现任何问题。这是我想要的工作,但不是:
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
几个错误例如:
错误C2061:语法错误:标识符'字符串'
错误C2146:语法错误:缺少';'在标识符“getManufacturer”之前
错误 C2061:语法错误:标识符“字符串” 错误 C2535:“Person::Person(void)”:成员函数已定义或声明
错误 C2146:语法错误:缺少 ';'在标识符“get_name”之前
错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认 int
错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int
错误 C2146:语法错误:缺少 ';'在标识符“getDriverLicenseNo”之前
I have a class Vehicle (vehicle.h and vehicle.cpp). Visual Studio is giving me errors if I don't put the includes inside of the header file. Why is this? In my previous 2 assignments I put the includes in the .cpp file and had no issues. Here is what I want to work but isn't:
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
Couple of errors for example:
error C2061: syntax error : identifier 'string'
error C2146: syntax error : missing ';' before identifier 'getManufacturer'
error C2061: syntax error : identifier 'string'
error C2535: 'Person::Person(void)' : member function already defined or declared
error C2146: syntax error : missing ';' before identifier 'get_name'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2146: syntax error : missing ';' before identifier 'getDriverLicenseNo'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在车辆头文件中声明
Person
的实例,因此编译器需要完整的声明。如果您使用的是指向人员的指针或引用,则只需使用class Person;
进行转发声明即可。编辑:此外,取出
using namespace std;
并在变量前加上std::
前缀。将来会省掉很多麻烦。EDIT2:您还需要在头文件中包含
。好的,就这样,我将尽力保持它的美观和简单。
当您的编译器处理您的实现文件 (.cpp) 时,它会包含您指定的标头(在本例中为
vehicle.h
和person.h
)。对于每个实现文件,编译器需要了解您使用的每种类型,以便它可以生成正确的代码。当它处理包含文件时,它仍然需要知道一切。因此,在您的
vehicle.h
头文件中,您使用的是Person
。当编译器遇到这个问题时,它需要知道如何构造 person。您的vehicle.cpp在vehicle.h
之前包含person.h
,所以没问题。 对于vehicle.cpp
。包含vehicle.h
但不包含person.h
的任何其他内容都会给您带来编译器错误。那么什么时候可以摆脱前向声明并使用指针或引用呢?
声明指针或引用不需要在头文件中告诉编译器有关该类或结构的任何信息。您只是告诉编译器您打算这样做。假设该类是这样向前声明的:
然后编译器会说“okee dokee,我会接受的”。然后,您将相关文件包含在您的实现中,编译器会明白您的意思,然后每个人都高兴地从酒吧走回家。
我认为,在您的案例中发生的情况是,车辆的实现文件在纸面上看起来不错,但其他内容包括
vehicle.h
并且没有任何关于Person
的线索。代码> 是。您的解决方案
如果必须的话,可以在
vehicle.h
中包含person.h
,否则更改该构造函数以引用 person(以及成员) ),并转发声明Person
。然而,不知道你的程序在做什么,我不能说即使通过引用传递也是正确的。请删除
using namespace std;
并将您的string
更改为std::string
:)You are declaring an instance of
Person
in your vehicle header file, therefore the compiler needs the full declaration. If you were using a pointer or reference to a person, you could simply forward declare it withclass Person;
.EDIT: Also, take out that
using namespace std;
and prefix your variables withstd::
. It'll save a lot of ball-ache in the future.EDIT2: You also need to include
<string>
in your header file.Ok, here goes, I'm going to try and keep it nice and simple.
When your compiler processes your implementation files (.cpp) it includes the headers you have specified (in this case, that would be
vehicle.h
andperson.h
). For every implementation file, the compiler needs to know about every single type that you use so that it can generate the correct code.When it processes an include file, it still needs to know everything. So in your
vehicle.h
header file, you are usingPerson
. At the point that the compiler hits that, it needs to know how to construct person. Yourvehicle.cpp
includesperson.h
beforevehicle.h
so, no problem. FORvehicle.cpp
. Anything else that includesvehicle.h
but does not includeperson.h
, will give you compiler errors.So when can you get away with a forward declaration and user a pointer or reference?
Declaring a pointer, or a reference does not require telling the compiler anything about that class or structure in the header file. You're merely telling the compiler that you have an intention to do so. Provided that the class is forward declared thusly:
Then the compiler says "okee dokee, I'll take that." Then you include the relevant file in your implementation, the compiler sees what you mean and everybody walks home from the bar happy.
What has happened in your case, I think, is that the implementation file for vehicle looks good on paper, but something else includes
vehicle.h
and there is no clue about what aPerson
is.Your solution
Either include
person.h
invehicle.h
if you must, otherwise change that constructor to take a reference to person (and the member), and forward declarePerson
. However, not knowing what your program is doing I can't say that even passing-by-reference is correct.And please, remove
using namespace std;
and change yourstring
's tostd::string
:)当您将另一个类的对象放入您的类中时,编译器需要知道该类的完整定义。记住这条规则的最简单方法是认识到,在知道 sizeof(Person) 之前,您无法知道 sizeof(Vehicle),编译器也不能。如果您先进行前向声明,则对另一个类的指针和引用是可以的。
When you put an object of another class into your class, the compiler needs to know the entire definition of that class. The easiest way to remember this rule is to realize that you can't know sizeof(Vehicle) until you know sizeof(Person), and neither can the compiler. Pointers and references to another class are OK if you do a forward declaration first.
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++ 引用,永久附加到特定实例)。Does person.h contain the line
#include "vehicle.h"
? Circular dependencies are harder to manage in C++ than e.g. Java or C#. You can easily get into a situation where you need#include "Person.h"
before#include "Vehicle.h"
, but you also need#include "Vehicle.h"
before#include "Person.h"
.In many cases you have to tell the compiler "Person is the name of a class, but I'm not ready to give you the definition yet". For that you can say
class Person;
This unravels the circular reference problem.Also, making lots of copies of a
Person
object probably doesn't make sense, but that's what you're doing with pass-by-value. It really looks like you're coming from a Java or C# environment, where variables of class type automatically (and always) were references. In C++, you have to ask for a reference via eitherPerson*
(a pointer, can be changed to point to a different instance, like Java and C# references) orPerson&
(a C++ reference, permanently attached to a particular instance).