Inheritance
Inheritance allows a new class to be based on an existing class. The new class inherits all the member variables and functions, except for the constructors and destructor.
"Is a" Relationship
Constructor and Destructor
//Vehicle.h
#ifndef VEHICLE_H
#define VEHICLE_H
#include <iostream>
#include <string>
class Vehicle
{
private:
std::string producer;
public:
//constructor
Vehicle(std::string s);
std::string getProducer() const {return producer;}
void setProducer(std::string producer);
std::string toString();
~Vehicle();
};
#endif
//Vehicle.cpp
#include <iostream>
#include <string>
#include "Vehicle.h"
//constructor
Vehicle::Vehicle(std::string s):producer(s)
{
std::cout<<"Vehicle Constructor ..."<<std::endl;
}
void Vehicle::setProducer(std::string producer)
{
this->producer = producer;
}
std::string Vehicle::toString()
{
std::string temp;
temp = "Vehicle Producer: "+producer;
return temp;
}
Vehicle::~Vehicle()
{
std::cout<<"Vehicle Destructor ..."<<std::endl;
}
//Car.h
#ifndef CAR_H
#define CAR_H
#include <iostream>
#include <string>
#include "Vehicle.h"
class Car : public Vehicle
{
private:
std::string model;
public:
//constructor
Car(std::string p, std::string m);
std::string getModel() const {return model;}
void setModel(std::string model);
std::string toString();
~Car();
};
#endif
//Car.cpp
#include <iostream>
#include <string>
#include "Vehicle.h"
#include "Car.h"
//constructor
Car::Car(std::string p, std::string m):Vehicle(p), model(m)
{
std::cout<<"Car Constructor ..."<<std::endl;
}
void Car::setModel(std::string model)
{
this->model = model;
}
std::string Car::toString()
{
std::string temp;
temp = "Car Producer: "+getProducer()+" Model: "+model;
return temp;
}
Car::~Car()
{
std::cout<<"Car Destructor ..."<<std::endl;
}
//Bicycle.h
#ifndef BICYCLE_H
#define BICYCLE_H
#include <iostream>
#include <string>
#include "Vehicle.h"
class Bicycle : public Vehicle
{
private:
int size;
public:
//constructor
Bicycle(std::string p, int s);
int getSize() const {return size;}
void setSize(int s);
std::string toString();
~Bicycle();
};
#endif
//Bicycle.cpp
#include <iostream>
#include <string>
#include "Vehicle.h"
#include "Bicycle.h"
//constructor
Bicycle::Bicycle(std::string p, int s) : Vehicle(p), size(s)
{
std::cout<<"Bicycle Constructor ..."<<std::endl;
}
void Bicycle::setSize(int s)
{
size = s;
}
std::string Bicycle::toString()
{
std::string temp;
temp = "Bicycle Producer: "+getProducer()+" Size: "+std::to_string(size);
return temp;
}
Bicycle::~Bicycle()
{
std::cout<<"Bicycle Destructor ..."<<std::endl;
}
- Although the private members are inherited, they are invisible to child. They can be accessed by the member functions of the parent class
- Inheritance does not work in reverse. It is impossible for a parent class to call a member funciton of a child class
- Pass arguments to the parent class by calling the constructor of the parent
- Car(std::string p, std::string m):Vehicle(std::string p), in the definition of a constructor, not in a prototype
- Creating a child object, the constructor of parent will be called first, then the constructor of child will be called; when the object is deleted, the destructor of child will be called first, then the destructor of parent will be called
Class Access Specification
The default access specification is private, class Parent : Grand equals to class Parent : private Grand
Redefine Functions
//Grand.h
#ifndef GRAND_H
#define GRAND_H
#include <iostream>
class Grand
{
private:
int gx;
protected:
int gy;
public:
int gz;
Grand()
{
gx = 1;
gy = 2;
gz = 3;
}
int getX() const {return gx;}
int getY() const {return gy;}
int getZ() const {return gz;}
void display()
{
std::cout<<gx<<" "<<gy<<" "<<gz<<std::endl;
}
};
#endif
//Parent.h
#ifndef PARENT_H
#define PARENT_H
#include <iostream>
#include "Grand.h"
class Parent : public Grand
{
private:
int px;
protected:
int py;
public:
int pz;
Parent() : Grand()
{
px = 10;
py = 20;
pz = 30;
}
int getX() const {return px;}
int getY() const {return py;}
int getZ() const {return pz;}
void display()
{
std::cout<<px<<" "<<py<<" "<<pz<<std::endl;
std::cout<<Grand::getX()<<" "<<gy<<" "<<gz<<std::endl;
}
};
#endif
//Child.h
#ifndef CHILD_H
#define CHILD_H
#include <iostream>
#include "Grand.h"
#include "Parent.h"
class Child : public Parent
{
private:
int cx;
protected:
int cy;
public:
int cz;
Child() : Parent()
{
cx = 100;
cy = 200;
cz = 300;
}
int getX() const {return cx;}
int getY() const {return cy;}
int getZ() const {return cz;}
void display()
{
std::cout<<cx<<" "<<cy<<" "<<cz<<std::endl;
std::cout<<Parent::getX()<<" "<<py<<" "<<pz<<std::endl;
std::cout<<Grand::getX()<<" "<<gy<<" "<<gz<<std::endl;
}
};
#endif
- Protected members of a base class can be accessed by functions in a derived class
- Call Grand::getX() from Parent
- Call Grand::getX() and Parent::getX() from Child
Multiple Inheritance
//Faculty.h
#ifndef FACULTY_H
#define FACULTY_H
#include <iostream>
#include <string>
class Faculty
{
private:
std::string title;
public:
Faculty(std::string t):title(t)
{
std::cout<<"Faculty Constructor ..."<<std::endl;
}
std::string getTitle() const {return title;}
std::string toString()
{
std::string temp;
temp = "Faculty Title: "+title;
return temp;
}
~Faculty()
{
std::cout<<"Faculty Destructor ..."<<std::endl;
}
};
#endif
//Student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
class Student
{
private:
std::string major;
public:
Student(std::string m)
{
major = m;
std::cout<<"Student Constructor ..."<<std::endl;
}
std::string getMajor() const {return major;}
std::string toString()
{
std::string temp;
temp = "Student Major: "+major;
return temp;
}
~Student()
{
std::cout<<"Student Destructor ..."<<std::endl;
}
};
#endif
//TA.h
#ifndef TA_H
#define TA_H
#include <iostream>
#include "Faculty.h"
#include "Student.h"
class TA : public Faculty, Student
{
private:
std::string course;
public:
TA(std::string t, std::string m, std::string c):Faculty(t), Student(m), course(c)
{
std::cout<<"TA Constructor ..."<<std::endl;
}
std::string getCourse() const {return course;}
std::string toString()
{
std::string temp;
temp = "TA Title: "+getTitle()+" Major: "+getMajor()+" Course: "+course;
return temp;
}
~TA()
{
std::cout<<"TA Destructor ..."<<std::endl;
}
};
#endif
//main.cpp
#include <iostream>
#include <string>
#include "TA.h"
int main(int argc, char *argv[])
{
TA ta("GA", "CS", "CSC115");
std::cout<<ta.toString()<<std::endl;
return 0;
}
Constructor, Copy Constructor, Move Constructor, Copy Assignment, Move Assignment, Destructor
//V.h
#ifndef V_H
#define V_H
#include <iostream>
#include <string>
class V
{
private:
int size;
int *array;
public:
//constructor
V(int s):size(s)
{
std::cout<<"Constructor ..."<<std::endl;
array = new int[size];
for(int i = 0; i < size; i++)
array[i] = 10*i;
std::cout<<"----End Constructor ..."<<std::endl;
}
//copy constructor
V(const V &right):size(right.size), array(size?new int [size]:nullptr)
{
std::cout<<"Copy Constructor ..."<<std::endl;
std::copy(right.array, right.array+size, array);
std::cout<<"----End Copy Constructor ..."<<std::endl;
}
//move constructor
V(V && right):size(0), array(nullptr)
{
std::cout<<"Move Constructor ..."<<std::endl;
size = right.size;
array = right.array;
right.size = 0;
right.array = nullptr;
std::cout<<"----End Move Constructor ..."<<std::endl;
}
int *getAddress() const {return array;}
int getSize() const {return size;}
void display() const
{
for(int i = 0; i < size; i++)
std::cout<<array[i]<<" ";
std::cout<<std::endl;
}
std::string toString() const
{
std::string str = "V: ";
for(int i = 0; i < size; i++)
str += std::to_string(array[i])+" ";
return str;
}
V & time(int n)
{
for(int i = 0; i < size; i++)
array[i] *= n;
return *this;
}
//copy assignment
const V& operator=(const V &right)
{
std::cout<<"Copy Assignment ..."<<size<<std::endl;
if(this != &right)
{
V temp(right);
//std::swap(size, temp.size);
//std::swap(array, temp.array);
std::swap(*this, temp);
}
std::cout<<"----End Assignment ..."<<std::endl;
return *this;
}
//move assignment
V & operator=(V&& right)
{
std::cout<<"Move Assignment ..."<<std::endl;
if(this != &right)
{
delete [] array;
array = 0;
size = 0;
size = right.size;
array = right.array;
right.size = 0;
right.array = nullptr;
}
std::cout<<"----End Move Assignment ..."<<std::endl;
return *this;
}
~V()
{
std::cout<<"Destructor ..."<<size<<std::endl;
delete array;
array = 0;
size = 0;
}
};
#endif
//VV.h
#ifndef VV_H
#define VV_H
#include <iostream>
#include <string>
#include "V.h"
class VV : public V
{
private:
int type;
public:
//constructor inheritance
VV(int t, int s):type(t), V(s)
{
std::cout<<"WW Constructor ..."<<std::endl;
std::cout<<"----End WW Constructor ..."<<std::endl;
}
//copy constructor inheritance
VV(const VV &right):type(right.type), V(right)
{
std::cout<<"VV Copy Constructor ..."<<std::endl;
std::cout<<"----End VV Copy Constructor ..."<<std::endl;
}
//move constructor
VV(VV && right):type(right.type), V(std::move(right))
{
std::cout<<"VV Move Constructor ..."<<std::endl;
std::cout<<"----End VV Move Constructor ..."<<std::endl;
}
void display() const
{
std::cout<<"Type: "<<type<<" -- ";
V::display();
}
//copy assignment
const VV& operator=(const VV &right)
{
std::cout<<"VV Copy Assignment ..."<<std::endl;
type = right.type;
V::operator=(right);
std::cout<<"----End VV Assignment ..."<<std::endl;
return *this;
}
//move assignment
VV & operator=(VV&& right)
{
std::cout<<"VV Move Assignment ..."<<std::endl;
type = right.type;
V::operator=(std::move(right));
std::cout<<"----End VV Move Assignment ..."<<std::endl;
return *this;
}
~VV()
{
std::cout<<"VV Destructor ..."<<std::endl;
}
};
#endif
//main.cpp
#include <iostream>
#include "VV.h"
int main(int argc, char *argv[])
{
//V constructor
//VV constructor
VV vv(1, 2);
vv.display();//0 10
//V copy constructor
//VV copy constructor
VV vv2(vv);
vv.display();//0 10
vv2.display();//0 10
//V move constructor
//VV move constructor
VV vv3(std::move(vv));
vv.display();//empty
vv3.display();//0 10
//VV copy assignment
//V copy assignment
//V copy constructor, temp(right)
//V move assignment, swap
//V move assignment
//V move assignment
VV vv4(2, 4);
vv4.display();//0 10 20 30
vv4 = vv3;
vv3.display();//0 10
vv4.display();//0 10
//VV move assignment
//V move assignment
VV vv5(3, 8);
vv5.display();//0 10 20 30 40 50 60 70
vv4 = std::move(vv5);
vv5.display();//empty
vv4.display();//0 10 20 30 40 50 60 70
return 0;
}