Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Inheritance in Separate Files Using #include and Inclusion Guards

I am new to Stack Overflow and am teaching myself C++, but am still quite a beginner. After completing a nice chunk of the book I am using (which may be considered out dated and/or not a great book) I decided to re-enforce some concepts by trying them on my own, referencing the book only if needed, but I appear to be stuck. The concepts I am trying to tackle are inheritance, polymorphism, abstract data types (ADT), and separating the code for my classes into header files (.h) and C++ file (.cpp). Sorry in advance for the wall of text, I just want to be clear and specific where I need to be.

So, my goal is to create simple shape classes that inherit from one another where applicable. I have four classes: myPoly, myRectangle, myTriangle, and mySquare. myPoly, if I understood this concept correctly, should be an ADT since one of the methods is a pure virtual function (area method), since creating a myPoly object isn't something I would want a user of my classes to do. myRectangle and myTriangle both derive from myPoly and in turn mySquare derives from myRectangle. I've also included my test program where I planned on testing my classes. I am using Code::Blocks 10.05 and keep getting the following error when I build my test.cpp program:

undefined reference to 'myPoly::myPoly()' 

I get 42 similar errors all for the methods of the myPoly class. This happens when I try to build the .cpp files for myRectangle and myTriangle too. With the research I tried to do on the problems I been running into with this little project I feel like something is wrong with my inclusion guards or my #include statements, and something isn't getting included properly or is getting included too many times. At first I was providing the .cpp file for myPoly to myRectangle and myTriangle, but read in a couple of places that including the .h file for myPoly is more efficient and some how automatically include its .cpp. If anyone can provide some insight on that, it would be greatly appreciated. I also remember something about how using quotes in your inclusion statements is different than using the angle brackets. Below are all nine files that I have made for my little project. Most of the comments are little notes or reminders to me.

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; } 

I am very curious as to why I am getting these errors or why something I did may not be considered good/best practice, as opposed to just receiving a line of code to make my errors go away.

like image 739
RIBdot Avatar asked Jul 31 '12 19:07

RIBdot


People also ask

How do you extend a class from another file in C++?

This kind of class extension is not possible in C++ . But you can inherit a class from the original source file and add new functions in your source file. Show activity on this post. There's a way to actually do this, but it requires the compiler to support #include_next .

How does C support multiple inheritance?

Multiple Inheritance in C++ Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes. The constructors of inherited classes are called in the same order in which they are inherited.

Does C language support multiple inheritance?

Multiple Inheritance in C++ Multiple inheritance occurs when a class inherits from more than one base class. So the class can inherit features from multiple base classes using multiple inheritance. This is an important feature of object oriented programming languages such as C++.

How does inheritance work in C?

In C, inheritance can be achieved by maintaining a reference to the base class object in the derived class object. With the help of the base class' instance, we can access the base data members and functions.


1 Answers

Your inclusion guards look fine. If they were not, you would most likely get a compiler error, including file and line number information. The error you posted seems more like a linker error.

However, there is one "problem" with your code. As a general rule, you should only #include .h files and not .cpp files.

Now to get to the solution: I am unfamiliar with Code::Blocks myself. However, I hope I can give some general information that will point you in the right direction. Some compilers I have used in the past by default allowed me to compile a single C++ file and run the program. To compile a program with more than one file, I had to create a project. (Most modern compilers force you to create a project from the start.) With this in mind, I would suggest you check out how to create a project for your program in Code::Blocks.

like image 139
Code-Apprentice Avatar answered Sep 20 '22 06:09

Code-Apprentice