如何在另一个自己创建的类头文件中包含一个自创的类?

时间:2010-12-21 18:27:41

标签: c++ class header

假设我创建了两个类:轮胎和汽车。

所以我有四个文件:Tires.cpp,Tires.h,Car.cpp,Car.h。

Car构造函数将Tires作为参数。但我不知道如何修改Car.h 包括Tires.h。

这是我到目前为止所做的事情(注意:它们位于不同的文件中)

Tires.h

#include <iostream>
using namespace std;

class Tires
{
private:
    int numTires;

public:
    Tires();
};

Tires.cpp

#include <iostream>
#include "Tires.h"
using namespace std;

Tires::Tires()
{
    numTires = 4;
}

Car.h

#include <iostream>
#include "Tires.h" 
using namespace std;

class Tires; // Tried taking out forward declaration but still didn't work

class Car
{
private:
    Tires tires;

public:
    Car(Tires);   // Edited. Thanks to Noah for pointing out.

};

Car.cpp

#include <iostream>
#include "Car.h"
#include "Tires.h"
using namespace std;

Car::Car(Tires _tires)
{
    tires = _tires;
}

由于

5 个答案:

答案 0 :(得分:4)

你的方法似乎很好。

标题包含其他标题时要记住的一件事是,您可能会发现需要包含include guard:

// At the start of Tires.h:
//

// Only delcare this stuff if this is the first time including Tires.h:
//
#ifndef __myproject_Tires_h__
#define __myproject_Tires_h__

class Tires
{
   // [snip]
};

// Close the #ifdef above...
//
#endif

这可以防止您声明“class Tire {”等。多次,Tires.h恰好包含两次。

另一个是不需要Car.h中的这一行:

class Tires;

如果您想要声明Tires*Tires&,但要做下一步做的事情,这可能很有用:

class Car
{
private:
   Tires tires;

...要求Tires成为“完整类型”,因为它的大小是已知的等等。无论如何,你已经完成了#include "Tires.h"

最后,有些人认为在标题中包含using语句是不好的形式。通过将std作为使用此标头的所有文件的全局命名空间引入,可以打破命名空间。想象一下,如果每个标头都这样做,并为多个名称空间做了这样做。最终,这与名称空间不存在相同,并且更有可能发生冲突。

答案 1 :(得分:1)

您需要的一件事是"include guards",这样您就不会因重新定义而产生一堆编译器错误。

在每个标题文件中添加以下内容:

#ifndef TIRES_H
#define TIRES_H

// contents of the header file...

#endif

当然,根据每个文件的需要更改用于宏保护(TIRES_H)的名称。宏名称必须是唯一的 - 基于头文件名称通常是足够好的。此外,许多(大多数?)编译器支持#pragma once预处理指令,该指令可防止标题被多次处理,但我仍然通常使用标准包含保护。

这允许标题被包含多次,因为保护会导致文件的后续包含基本上跳过整个内容。

几乎所有C / C ++标头都应该包含防护,因此用户无需担心是否已包含必要的标头(例外情况是在不同时间包含需要重新定义内容的标头 - 这是一种非常罕见的技术)。包含警戒还可以使头文件(如示例中的cars.h)包含他们所需的标题,而不考虑其他可能还包含标题的内容,因此您的标题可以是自我包含,可以包含在任何顺序中。

答案 2 :(得分:0)

你已经在Car.h中包含了Tires.h.您还可以在Car.h中获得轮胎类的前向声明。你应该删除包含或前向声明。由于你没有将轮胎作为参考或指针处理,因此你需要轮胎类的“行为”,你应该消除前向声明。

答案 3 :(得分:0)

您基本上已经回答了自己的问题,只是您的Car(Tires)接口尚未声明Car构造函数。

但我实际上并不这样做。你的构造函数应该是Car(Tires const&),这样你就可以简单地使用你在Car.h中已经获得的前向声明,直到在Car.cpp中才包含Tires.h。你的其余代码可以保持不变,但我仍然会进行进一步的更改并使用初始化而不是在构造函数中赋值:

Car::Car(Tires const& _tires) : tires(_tires) {}

更进一步,我建议不要使用'_'作为任何名字的第一个字符。没有必要经常让人们对什么时候好,什么时候不好感到困惑。

答案 4 :(得分:0)

从所有文件中删除包含“using namespace std;

的行

从Car.h删除包含“class Tires;”的行,因为它包含在#include "Tires.h"

现在将所有头文件包装在标题保护中。