INHERITANCE: CONSTRUCTORS, DESTRUCTORS, HEADER FILES Pages 720 to 731 Anna Rakitianskaia, University of Pretoria
CONSTRUCTORS Constructors are used to create objects Object creation = initialising member variables persontype::persontype(string first, string last) firstname = first; lastname = last; } Both derived and base (child and parent) classes need constructors
CONSTRUCTORS OF DERIVED AND BASE CLASSES Child class inherits member variables of the parent class Problem: private variables of the parent class are not directly accessible from the child class Inherited private variables still have to be initialised!
CONSTRUCTORS OF DERIVED AND BASE CLASSES Can we use a constructor to initialize all member variables, including the private inherited ones? Yes! However, parent constructors are not inherited We can write child class constructor such that it executes the constructor of the parent class
CONSTRUCTORS OF DERIVED AND BASE CLASSES We can write child class constructor such that it also executes the constructor of the parent class Parent constructor: rectangetype::rectangetype(double l, double w) setdimension(l, w); } Child constructor: boxtype::boxtype(double l, double w, double h) : rectangletype(l, w) height = h; }
CONSTRUCTORS OF DERIVED AND BASE CLASSES Line 1: executes the parent class constructor Line 2: executes the parent class constructor with values 6.0, 5.0, then executes the child class constructor In order: parent constructors precede child constructors
CONSTRUCTOR WITH DEFAULT PARAMETERS AND INHERITANCE HIERARCHY Child classes can also have default constructors, and constructors with default parameters Constructors of child classes can pass default parameters to the parent class constructors Declare constructor with default parameters: boxtype(double l = 0, double w = 0, double h = 0); Implement the constructor: boxtype::boxtype(double l, double w, double h) : rectangletype(l, w) height = h; }
DESTRUCTORS IN A DERIVED CLASS Destructors deallocate dynamic memory (i.e. pointers) boxtype::~boxtype() // deallocate memory! } Both child and parent classes may have destructors When a child class object goes out of scope (out of } where it was defined), it automatically invokes a destructor When the destructor of the child class executes, it automatically invokes the destructor of the parent class No explicit reference from child destructor to parent destructor is necessary Reverse order: child destructors precede parent destructors
HEADER FILE OF A DERIVED CLASS When we define a new class, we create a new header file (.h) To create child classes that inherit from previously defined parent classes, header files of the new classes should contain commands (#include) that specify where to look for the definitions of the base classes:
MULTIPLE INCLUSIONS OF A HEADER FILE The preprocessor command (#include) is used to include a header file in a program The preprocessor processes the program before it is compiled
MULTIPLE INCLUSIONS OF A HEADER FILE Consider the following code: Both testa.h and headertest.cpp include test.h thus, test.h is included twice This will result in compile errors due to multiple definitions of ONE and TWO Solution: use identifiers in the headers (next slide)
MULTIPLE INCLUSIONS OF A HEADER FILE #ifndef H_test means if not defined H_test #define H_test means define H_test #endif means end if Now, ONE and TWO are declared with a unique preprocessor identifier H_test
PUTTING EVERYTHING TOGETHER Box inheriting from Rectangle: a complete (constructor) example boxtype -height: double +boxtype(double l, double w, double h) +getheight() const: double +area() const: double +volume() const: double +setdimension(double l, double w, double h): void +print() const: void rectangletype -length: double -width: double +rectangletype(double l, double w) +getlength() const: double +getwidth() const: double +area() const: double +perimeter() const: double +setdimension(double l, double w): void +print() const: void
CONSTRUCTORS: RECTANGLETYPE HEADER #ifndef RECTANGLETYPE_H #define RECTANGLETYPE_H class rectangletype private: double length; double width; public: rectangletype(double l = 0, double w = 0); double getlength() const; double getwidth() const; double area() const; double perimeter() const; void setdimension(double l, double w); void print() const; }; #endif
RECTANGLETYPE IMPLEMENTATION #include rectangletype.h rectangletype::rectangletype(double l, double w) setdimension(l, w); } void rectangletype::setdimension(double l, double w) if(l >= 0) length = l; else length = 0; } if(w >= 0) width = w; else width = 0; // etc
BOXTYPE HEADER #ifndef BOXTYPE_H #define BOXTYPE_H #include rectangletype.h class boxtype : public rectangletype private: double height; public: boxtype(double l = 0, double w = 0, double h = 0); double getheight() const; double area() const; double volume() const; void setdimension(double l, double w, double h); void print() const; }; #endif
BOXTYPE IMPLEMENTATION #include boxtype.h boxtype::boxtype(double l, double w, double h) : rectangletype(l, w) height = h; } void boxtype::setdimension(double l, double w, double h) rectangletype::setdimension(l, w); } if(h >= 0) height = h; else height = 0; // etc
QUESTION TIME Next lecture: C++ stream classes Inheritance as public, protected or private Composition Stay tuned!