Héritage C ++ dans des fichiers séparés à l'aide de #include et de protections d'inclusion
Je suis nouveau Débordement de Pile et je suis enseignant moi-même, C++, mais je suis encore un débutant. Après avoir terminé une bonne partie du livre que je suis en utilisant (ce qui peut être considéré comme hors-daté et/ou pas un grand livre), j'ai décidé de ré-appliquer certains concepts en les essayant sur mon propre, la référence à la livre, mais seulement si nécessaire, mais je semble être coincé. Les concepts que je suis en train d'essayer de s'attaquer sont l'héritage, le polymorphisme, les types de données abstraites (ADT), et en séparant le code pour mes classes dans des fichiers d'en-tête (.h) et le fichier C++ (.rpc). Désolé d'avance pour le pavé de texte, je veux juste être clair et précis où je dois être.
Donc, mon but est de créer une forme simple les classes qui en héritent l'un de l'autre, le cas échéant. J'ai quatre classes: myPoly, myRectangle, myTriangle, et mySquare. myPoly, si j'ai bien compris ce concept, devraient être un ADT depuis l'une des méthodes est une fonction virtuelle pure (méthode de la zone), car la création d'un myPoly objet n'est pas quelque chose que je voudrais un utilisateur de mes classes à faire. myRectangle et myTriangle proviennent tous deux myPoly et à son tour mySquare dérive de myRectangle. J'ai aussi pris mon programme de test où je voulais tester mes classes. J'utilise Code::Blocks 10.05 et reçois le message d'erreur suivant lorsque je créer mon test.cpp programme:
undefined reference to 'myPoly::myPoly()'
- Je obtenir 42 des erreurs similaires à tous pour les méthodes de la myPoly classe. Ce qui se passe quand j'essaie de construire la .fichiers cpp pour myRectangle et myTriangle trop. Avec la recherche, j'ai essayé de faire sur les problèmes que j'ai été en cours d'exécution avec ce petit projet que j'ai envie de quelque chose qui est mal à mes inclusion des gardes ou mes instructions #include, et quelque chose qui n'est pas inclus correctement ou s'il est arriver aussi compris de nombreuses fois. J'ai d'abord été de fournir l' .fichier cpp pour myPoly à myRectangle et myTriangle, mais lu dans un couple de lieux dont la .h fichier pour myPoly est plus efficace, et certains comment inclure automatiquement son .rpc. Si quelqu'un peut nous éclairer sur ce point, il serait grandement apprécié. Je me rappelle aussi quelque chose sur la façon d'utiliser les citations dans votre inclusion des déclarations est différent que d'utiliser les crochets. Ci-dessous sont tous neuf les fichiers que j'ai fait pour mon petit projet. La plupart des commentaires sont des petites notes ou des rappels pour moi.
myPoly.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//header file for Polygon class
#ifndef MYPOLY_H
#define MYPOLY_H
class myPoly
{
public:
//constructor
//const reference pass because the values w and h don't change and reference avoid the time it takes to copy large
// objects by value (if there were any)
myPoly();
myPoly(const float & w, const float & h);
//destructor
virtual ~myPoly();
//accessors
float getWidth();
float getHeight();
void setWidth(const float & w);
void setHeight(const float & h);
virtual float area() = 0;
private:
float width, height;
};
#endif
myPoly.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myPoly class
#include "myPoly.h"
//constructor
myPoly::myPoly()
{
setWidth(10);
setHeight(10);
}
myPoly::myPoly(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
//destructor
myPoly::~myPoly() {}
//accessors
float myPoly::getWidth() {return width;}
float myPoly::getHeight() {return height;}
void myPoly::setHeight(const float & w) {width = w;}
void myPoly::setWidth(const float & h) {height = h;}
//pure virtual functions have no implementation
//area() is handled in the header file
myRectangle.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myRectangle class
#ifndef MYRECTANGLE_H
#define MYRECTANGLE_H
#include "myPoly.h"
class myRectangle : public myPoly
{
public:
//constructor
myRectangle();
myRectangle(const float & w, const float & h);
//destructor
~myRectangle();
//this doesn't need to be virtual since the derived class doesn't override this method
float area();
};
#endif
myRectangle.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementaion file for the myRectangle class
//get a vauge compiler/linker error if you have virtual methods that aren't implemented (even if it ends up being just
// a 'stub' method, aka empty, like the destructor)
#include "myRectangle.h"
myRectangle::myRectangle()
{
setWidth(10);
setHeight(10);
}
myRectangle::myRectangle(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
myRectangle::~myRectangle()
{
}
float myRectangle::area()
{
return getWidth() * getHeight();
}
myTriangle.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myTriangle class
#ifndef MYTRIANGLE_H
#define MYTRIANGLE_H
#include "myPoly.h"
//imagine the triangle is a right triangle with a width and a height
// |\
// | \
// | \
// |___\
class myTriangle : public myPoly
{
public:
//constructors
myTriangle();
myTriangle(const float & w, const float & h);
//destructor
~myTriangle();
//since nothing derives from this class it doesn't need to be virtual and in turn neither does the destructor
float area();
};
#endif
myTriangle.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myTriangle class
#include "myTriangle.h"
myTriangle::myTriangle()
{
setWidth(10);
setHeight(10);
}
myTriangle::myTriangle(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
myTriangle::~myTriangle()
{
}
float myTriangle::area()
{
return getWidth() * getHeight() / 2;
}
mySquare.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for mySquare class
#ifndef MYSQUARE_H
#define MYSQUARE_H
#include "myRectangle.cpp"
class mySquare : public myRectangle
{
public:
//constructors
mySquare();
//explicity call the myRectangle constructor within this implementation to pass w as width and height
mySquare(const float w);
//destructor
~mySquare();
};
#endif
mySquare.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for mySquare class
#include "mySquare.h"
mySquare::mySquare()
{
setWidth(10);
setHeight(10);
}
mySquare::mySquare(const float w)
{
myRectangle::myRectangle(w, w);
}
mySquare::~mySquare()
{
}
test.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//main class that uses my shape classes and experiments with inheritance, polymorphism, and ADTs
#include "myRectangle.cpp"
//#include "mySquare.cpp"
#include "myTriangle.cpp"
#include <iostream>
int main()
{
myPoly * shape = new myRectangle(20,20);
return 0;
}
Je suis très curieux de savoir pourquoi j'obtiens ces erreurs ou pourquoi quelque chose que je ne peut pas être considérées comme de bonnes/meilleures pratiques, plutôt que de simplement recevoir une ligne de code pour faire mes erreurs disparaissent.
source d'informationauteur RIBdot
Vous devez vous connecter pour publier un commentaire.
Votre inclusion gardes ont l'air bien. Si non, vous serait le plus susceptible d'obtenir une erreur de compilateur, y compris de fichier et le numéro de ligne de l'information. L'erreur que vous avez posté ressemble plus à une erreur de l'éditeur de liens.
Cependant, il y a un "problème" avec votre code. En règle générale, vous ne devriez
#include
.h de fichiers et pas .fichiers cpp.Maintenant, pour arriver à la solution: je suis pas familier avec Code::Blocks moi-même. Cependant, j'espère que je peux donner quelques informations générales qui vous orientera dans la bonne direction. Certains compilateurs j'ai utilisé dans le passé par défaut m'a permis de compiler un seul fichier C++ et exécuter le programme. Pour compiler un programme avec plus d'un fichier, j'ai dû créer un projet. (Plus les compilateurs modernes vous forcer à créer un projet depuis le début.) Avec cela à l'esprit, je vous suggère de vérifier comment créer un projet pour votre programme dans Code::Blocks.
À partir d'un code point (du moins ce que j'ai regardé à travers), il semble assez bon, mais:
Il y a deux choses à considérer:
Ne pas inclure directement fichiers cpp. Par exemple, dans mySquare.h,
#include "myRectangle.cpp"
devrait être#include "myRectangle.h"
. Vous voulez être, y compris l'interface/les déclarations prévues dans le fichier d'en-tête que dire du programme de la façon de faire la classe, et pas seulement les définitions de fonction.Deuxièmement, assurez-vous que vous êtes à la compilation avec tous vos fichiers de l'objet. Je ne sais pas de blocs de code, mais si vous étiez à l'aide de g++ ou quelque chose comme ça, vous voulez le faire
g++ main.cpp myPoly.cpp mySquare.cpp etc.
pour tous les fichiers. Une erreur peut se produire si vous oubliez myPoly.cpp par exemple, parce que pas de définition de ses fonctions.Tout semble parfait, en fait. Il est probablement tout aussi simple que de ne pas y compris myPoly.obj lorsque vous lier votre programme. Je ne suis pas familier avec Code::Blocks (même si je sais que c'est assez populaire), mais je suppose que si vous venez, par exemple, cliquez sur test.cpp et choisissez "Exécuter en", que Code::Blocks allons essayer de construire un programme à partir d'un seul fichier source. Vous aurez besoin d'inclure tous les fichiers source dans chaque programme que vous créez.
En outre à ce que le otehr gars m'a dit: Vous ne faites pas de l'héritage de la droite...
Lorsque vous ne
Vous devez déclarer l'enfant du constructeur de la manière suivante:
L'enfant ne doit être construit après que le père a achevé la construction d'.