Comment inclure une auto-créé classe dans une autre auto-création de la classe fichier d'en-tête?
Dire que j'ai créé deux classes: les Pneus et la Voiture.
J'ai donc quatre fichiers: Tires.cpp, Pneus.h, Car.cpp, Voiture.h.
La Voiture constructeur de Pneus comme paramètre. Mais je ne suis pas sûr de la façon de modifier la Voiture.h à
inclure des Pneus.h.
Voici ce que j'ai fait jusqu'à présent (note: ils sont dans des fichiers séparés)
Pneus.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;
}
Voiture.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;
}
Grâce
- yup, qui a l'air bien. alors, quelle est votre question? (votre titre ne fait pas de sens pour moi)
- En aparté, veuillez ne pas utiliser
using namespace std;
ou des déclarations similaires dans un fichier d'en-tête - vous obtenez toutes sortes de "intéressants" d'effets secondaires que lorsque vous faites affaire avec des symboles qui sont définies dans plusieurs espaces de noms. - Donc en gros, j'ai une classe de Voiture et les Pneus de la Classe. Constructeur de la classe Voiture prend une instance de Pneus de classe. Voici ce que j'ai fait (voir code ci-dessus) et il n'est pas compilé. Espérons que cela a du sens. Merci.
Vous devez vous connecter pour publier un commentaire.
Votre approche semble très bien ici.
Une chose à garder à l'esprit lorsque les en-têtes inclure d'autres en-têtes est que vous pouvez trouver, vous devez inclure une inclure garde:
Cela vous empêche de déclarer "
class Tire {
" et al. à plusieurs reprises, devraitTires.h
arriver à être inclus deux fois.Un autre, c'est que cette ligne dans
Car.h
n'est pas nécessaire:Cela peut être utile si vous souhaitez avoir de déclarations de
Tires*
ouTires&
, mais à faire ce que vous avez fait suivant:... il faut
Tires
être un "type complètes", de sa taille à être connu, etc. Vous êtes déjà couvert par que par le fait d'avoir#include "Tires.h"
de toute façon.Enfin, certains considèrent que c'est une mauvaise forme à
using
énoncé à l'intérieur d'un en-tête comme vous l'avez fait. Ce genre de pauses espaces de noms par la mise enstd
comme un espace de noms global pour tous les fichiers qui utilisent cet en-tête. Imaginez si chaque en-tête fait cela, et a plusieurs espaces de noms. Finalement, cela devient la même que il n'y a pas une telle chose comme des espaces de noms, et les collisions sont plus susceptibles.Une chose que vous avez besoin est "inclure des gardes" de sorte que vous n'avez pas d'obtenir un tas d'erreurs du compilateur en raison de la redéfinition.
Mettre quelque chose comme ce qui suit dans chacun de vous fichiers d'en-tête:
De cours, modifier le nom utilisé pour la macro de la garde (
TIRES_H
) en fonction de chaque fichier. Le nom de la macro doit être unique - en la fondant sur l'en-tête de nom de fichier est généralement assez bon. Aussi, beaucoup (la plupart?) les compilateurs de soutenir un#pragma once
prétraitées directive qui empêche les en-têtes d'être traité plus d'une fois, mais j'ai toujours utilise généralement la norme gardes.Cela permet des en-têtes inclus plus d'une fois, depuis que les gardes en cause ultérieure comprend du fichier à essentiellement passer la totalité de son contenu.
Presque tous les C/C++ en-têtes doivent avoir des gardes de sorte que les utilisateurs n'ont pas besoin de s'inquiéter de savoir si ou non nécessaire de l'en-tête a été déjà inclus (à l'exception des en-têtes qui ont besoin de redéfinir les choses différemment lorsqu'ils sont inclus à des moments différents - c'est assez rare technique). Comprenant des protections vous permettent également d'avoir des fichiers d'en-tête (comme
cars.h
dans votre exemple) inclure les en-têtes ils besoin, sans égard à ce qui pourrait également inclure les en-têtes, de sorte que vos en-têtes peuvent être autonomes et peuvent être inclus dans n'importe quel ordre.TIRES_H
pour chaque fichier d'en-tête.Vous avez déjà inclus Pneus.h en Voiture.h. Vous avez également une déclaration anticipée de la catégorie des Pneus de Voiture.h. Vous devez éliminer les inclure ou la déclaration anticipée. Comme vous ne le manipulez pas les Pneus comme référence ou un pointeur et vous devez donc le "comportement" de la catégorie Pneus, vous devez éliminer la déclaration anticipée.
Tire
ne serait pas de savoir s'il a déclaré l'un d'être membre deCar
. Il faudrait changer pour un pointeur ou une référence pour juste avant la déclaration de travaux.Vous avez déjà répondu à votre propre question, sauf que votre
Car(Tires)
constructeur doit encore être déclarées dans votreCar
interface.Mais je n'avais pas le faire de cette façon. Votre constructeur doit être
Car(Tires const&)
de sorte que vous pouvez simplement utiliser l'avant de la déclaration que vous avez déjà dans la Voiture.h et de ne pas inclure les Pneus.h jusqu'à Car.cpp. Le reste de votre code pourrait rester le même, mais je serais encore faire un changement et de l'utilisation de l'initialisation plutôt que de l'affectation dans le constructeur:Encore plus loin, je vous recommande de ne JAMAIS utiliser de '_' comme premier caractère dans n'importe quel nom. Il n'y a pas besoin de et trop souvent, les gens deviennent confus quand il est OK et quand il ne l'est pas.
À partir de tous les fichiers à supprimer la ligne contenant "
using namespace std;
"De Voiture.h supprimer la ligne contenant "
class Tires;
", comme on l'inclus à partir de#include "Tires.h"
Maintenant l'emballage de tous vos fichiers d'en-tête en-tête des gardes.