C++ Vererbung in Separate Dateien Mithilfe von #include und Integration Wachen
Ich bin neu auf Stack-Überlauf und unterrichte mich C++, bin aber noch ein ziemlicher Anfänger. Nach Abschluss ein schönes Stück des Buches, das ich mit (was als veraltet und/oder nicht ein tolles Buch) ich beschloss, re-erzwingen Sie einige Konzepte, indem Sie versuchen, Sie auf meine eigene, verweisen auf das Buch, nur wenn nötig, aber ich scheinen fest zu sein. Die Konzepte, die ich versuche zu bewältigen sind Vererbung, Polymorphie, abstrakte Datentypen (ADT), und die Trennung von code für meine Klassen in header-Dateien (.h) und C++ - Datei (.cpp). Sorry im Voraus für die wall of text, ich will einfach nur klar sein und bestimmte, wo ich sein muss.
So, mein Ziel ist das erstellen von einfachen shape-Klassen, Erben von einer anderen, wo anwendbar. Ich habe vier Klassen: myPoly, myRectangle, myTriangle, und mySquare. myPoly, wenn ich verstanden, dass dieses Konzept richtig ist, sollte eine ADT-da eine der Methoden ist eine rein virtuelle Funktion (area-Methode), da die Schaffung eines myPoly Objekt ist nicht etwas, ich würde wollen, dass ein Benutzer von meinem Unterricht zu tun. myRectangle und myTriangle beide kommen aus myPoly und wiederum mySquare stammt aus myRectangle. Ich habe auch meine test-Programm, wo ich geplant, sich auf Tests, die meine Klassen. Ich bin mit Code::Blocks 10.05 und erhalte die folgende Fehlermeldung, wenn ich bauen meine test.cpp Programm:
undefined reference to 'myPoly::myPoly()'
Bekomme ich 42 ähnliche Fehler für die Methoden der myPoly Klasse. Dies geschieht, wenn ich versuche zu bauen .cpp-Dateien für myRectangle und myTriangle zu. Mit der Forschung habe ich versucht zu tun, auf die Probleme, die ich gelaufen mit diesem kleinen Projekt, ich fühle mich wie etwas falsch mit meiner Aufnahme Wachen oder meine #include-Anweisungen, und so etwas ist nicht immer im Lieferumfang enthalten richtig oder ist immer enthalten zu viele Male. Auf den ersten ich war die .cpp-Datei, die für myPoly zu myRectangle und myTriangle, aber Lesen Sie in ein paar Plätze, einschließlich der .h-Datei für myPoly ist effizienter, und einige, wie automatisch enthalten sein .cpp. Wenn jemand Einblick auf das, es würde sehr geschätzt werden. Ich erinnere mich auch etwas darüber, wie der Verwendung von Anführungszeichen in deiner Aufnahme Aussagen, die anders ist als die Verwendung der Spitzen Klammern. Unten sind alle neun Dateien, die ich gemacht habe für mein kleines Projekt. Die meisten Kommentare sind kleine Notizen oder Erinnerungen für mich.
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;
}
Ich bin sehr neugierig, warum bin ich immer diese Fehler-oder warum etwas, was ich Tat, kann nicht als gute/beste Praxis, im Gegensatz zu nur erhalten eine code-Zeile, um meine Fehler Weg.
InformationsquelleAutor der Frage RIBdot | 2012-07-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Aufnahme Wachen gut Aussehen. Wenn Sie es nicht waren, würden Sie wahrscheinlich bekommen einen compiler-Fehler, einschließlich der Datei und der Zeilennummer-Informationen. Der Fehler, den Sie gepostet scheint mehr wie ein linker-Fehler.
Jedoch, es gibt ein "problem" mit Ihrem code. Als Allgemeine Regel gilt, sollten Sie nur
#include
.h-Dateien und nicht .cpp-Dateien.Nun zur Lösung zu gelangen: ich bin nicht vertraut mit Code::Blocks selbst. Aber, ich hoffe, ich kann einige Allgemeine Informationen, die zeigen wird Sie in die richtige Richtung. Einige Compiler, die ich in der Vergangenheit verwendet haben standardmäßig erlaubt, mich zu kompilieren einer einzelnen C++ - Datei und starten Sie das Programm. Kompilieren Sie ein Programm mit mehr als einer Datei, die ich hatte, um ein Projekt zu erstellen. (Die meisten modernen Compiler zwingen, Sie erstellen ein Projekt von Anfang an.) Mit diesem im Verstand, ich schlage vor, Sie überprüfen Sie Sie heraus, wie Sie ein Projekt erstellen, für Ihr Programm in Code::Blocks.
InformationsquelleAutor der Antwort Code-Apprentice
Von einem code-Punkt stehen (zumindest was ich sah), es sieht ziemlich gut aus, aber:
Gibt es zwei Dinge zu beachten:
Nicht direkt cpp-Dateien. Zum Beispiel, in mySquare.h
#include "myRectangle.cpp"
sollte#include "myRectangle.h"
. Sie wollen werden, einschließlich der Schnittstelle/Deklarationen in der header-Datei, die dem Programm sagen, wie man die Klasse, nicht nur die Funktion Definitionen.Zweite, stellen Sie sicher, dass Sie die Kompilierung mit all Ihren Objekt-Dateien. Ich weiß nicht, code-Blöcke, aber wenn Sie wurden mit g++ oder so etwas wie, dass Sie wollen, um zu tun
g++ main.cpp myPoly.cpp mySquare.cpp etc.
für alle Dateien. Ein Fehler wie diese können passieren, wenn Sie vergessen myPoly.cpp zum Beispiel, weil keine Definitionen für seine Funktionen enthalten sein würden.InformationsquelleAutor der Antwort John Humphreys - w00te
Sieht alles gut aus, eigentlich. Es ist wohl einfach nicht einschließlich myPoly.obj, wenn Sie link zu Ihrem Programm. Ich bin nicht vertraut mit Code::Blocks (obwohl ich weiß, es ist ziemlich beliebt), aber ich nehme an, wenn Sie nur, zum Beispiel, klicken Sie auf test.cpp und wählen Sie "Ausführen", dass Code::Blocks wird versuchen, zu bauen ein Programm vor, dass nur eine source-Datei. Sie müssen alle relevanten Quellcode-Dateien in jedem Programm, das Sie erstellen.
InformationsquelleAutor der Antwort Ernest Friedman-Hill
Zusätzlich zu dem, was die otehr Jungs gesagt: sind Sie nicht das Erbe Recht...
Wenn Sie
Müssen Sie erklären dem Kind den Konstruktor auf folgende Weise:
Muss das Kind erst gebaut werden, nachdem der Vater fertig bauen.
InformationsquelleAutor der Antwort KuramaYoko