How to include a self-created class in another self-created class's header file?
Say I have created two classes: Tires, and Car.
So I开发者_StackOverflow中文版 have four files: Tires.cpp, Tires.h, Car.cpp, Car.h.
The Car constructor takes Tires as its parameter. But I am not sure how to modify Car.h to include Tires.h.
Here's what I've done so far (note: they are in separate files)
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;
}
Thanks
Your approach seems fine here.
One thing to keep in mind when headers include other headers is that you may find you need to include an 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
This prevents you from declaring "class Tire {
" et al. multiple times, should Tires.h
happen to be included twice.
Another is that this line in Car.h
is not needed:
class Tires;
This may be useful if you want to have declarations of Tires*
or Tires&
, but to do what you did next:
class Car
{
private:
Tires tires;
... requires Tires
to be a "complete type", for its size to be known, etc. You're already covered by that by having #include "Tires.h"
anyway.
Lastly, some consider it bad form to have a using
statement inside a header as you have done. This kind of breaks namespaces by bringing in std
as a global namespace for all files that use this header. Imagine if every header did this, and did so for multiple namespaces. Eventually this becomes the same as there being no such thing as namespaces, and collisions are more likely.
One thing you need is "include guards" so that you don't get a bunch of compiler errors due to redefinition.
Put something like the following in each of you header files:
#ifndef TIRES_H
#define TIRES_H
// contents of the header file...
#endif
Of course, change the name used for the macro guard (TIRES_H
) as appropriate for each file. The macro name needs to be unique - basing it on the header file name is usually good enough. Also, many (most?) compilers support a #pragma once
preprocessed directive that prevents headers from being processed more than once, but I still generally use the standard include guards.
This allows headers to be included more than once, since the guards cause subsequent includes of the file to essentially skip the entire contents.
Almost all C/C++ headers should have include guards so users don't need to worry about whether or not a necessary header was already included (the exceptions are headers which need to redefine things differently when included at different times - this is a pretty rare technique). Include guards also enable you to have header files (like cars.h
in your example) include the headers they need without regard to what else might also include the headers, so your headers can be self-contained and can be included in any order.
You have already included Tires.h in Car.h. You also have a forward declaration of class Tires in Car.h. You should eliminate either the include or the forward declaration. As you don't handle Tires as reference or pointer and you thus need the "behavior" of class Tires, you should eliminate the forward declaration.
You've basically already answered your own question except that your Car(Tires)
constructor has yet to be declared in your Car
interface.
But I'd actually not do it that way. Your constructor should be Car(Tires const&)
so that you can simply use the forward declaration you've already got in Car.h and not include Tires.h until in Car.cpp. The rest of your code could stay the same, but I'd still make a further change and use initialization rather than assignment in the constructor:
Car::Car(Tires const& _tires) : tires(_tires) {}
Even further, I recommend not EVER using '_' as the first character in any name. There's no need to and too often people get confused about when it is OK and when it is not.
From all files delete line containing "using namespace std;
"
From Car.h delete line containing "class Tires;
" as it's included from #include "Tires.h"
Now wrap all your header file in header guards.
精彩评论