C++放置位置包括

发布于 2024-10-03 14:46:21 字数 3081 浏览 0 评论 0原文

我有一个车辆类(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神回复 2024-10-10 14:46:21

您正在车辆头文件中声明 Person 的实例,因此编译器需要完整的声明。如果您使用的是指向人员的指针或引用,则只需使用 class Person; 进行转发声明即可。

编辑:此外,取出 using namespace std; 并在变量前加上 std:: 前缀。将来会省掉很多麻烦。

EDIT2:您还需要在头文件中包含

好的,就这样,我将尽力保持它的美观和简单。

当您的编译器处理您的实现文件 (.cpp) 时,它会包含您指定的标头(在本例中为 vehicle.hperson.h)。对于每个实现文件,编译器需要了解您使用的每种类型,以便它可以生成正确的代码。

当它处理包含文件时,它仍然需要知道一切。因此,在您的 vehicle.h 头文件中,您使用的是 Person。当编译器遇到这个问题时,它需要知道如何构造 person。您的vehicle.cpp在vehicle.h之前包含person.h,所以没问题。 对于vehicle.cpp。包含 vehicle.h 但不包含 person.h 的任何其他内容都会给您带来编译器错误。

那么什么时候可以摆脱前向声明并使用指针或引用呢?

声明指针或引用不需要在头文件中告诉编译器有关该类或结构的任何信息。您只是告诉编译器您打算这样做。假设该类是这样向前声明的:

class Person;

然后编译器会说“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 with class Person;.

EDIT: Also, take out that using namespace std; and prefix your variables with std::. 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 and person.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 using Person. At the point that the compiler hits that, it needs to know how to construct person. Your vehicle.cpp includes person.h before vehicle.h so, no problem. FOR vehicle.cpp. Anything else that includes vehicle.h but does not include person.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:

class Person;

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

Your solution

Either include person.h in vehicle.h if you must, otherwise change that constructor to take a reference to person (and the member), and forward declare Person. 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 your string's to std::string :)

亚希 2024-10-10 14:46:21

当您将另一个类的对象放入您的类中时,编译器需要知道该类的完整定义。记住这条规则的最简单方法是认识到,在知道 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.

朦胧时间 2024-10-10 14:46:21

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 either Person* (a pointer, can be changed to point to a different instance, like Java and C# references) or Person& (a C++ reference, permanently attached to a particular instance).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文