4.2多继承和多重继承
多继承
class Person
{};
class Worker
{};
class Farmer:public Person,public Worker
{};
多重继承
class Person
{};
class Worker:public Person
{};
class Farmer:public Worker
巩固练习:定义worker工人类及children儿童类,worker类中定义数据成员m_strName姓名,children类中定义数据成员m_iAge年龄,定义ChildLabourer童工类,公有继承工人类和儿童类。在main函数中通过new实例化ChildLabourer类的对象,并通过该对象的调用worker及children类中的成员函数,最后销毁该对象,体会多继承的继承特性及构造函数及析构函数的执行顺序
#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
class worker
{
public:
worker(string name)
{
m_strName = name;
cout << "worker()" << endl;
}
~worker()
{
cout << "~worker()" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
};
protected:
string m_strName;
};
class children
{
public:
children(int age)
{
m_iAge = age;
cout << "children()" << endl;
}
~children()
{
cout << "~children()" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
};
protected:
int m_iAge;
};
class childlabourer :public worker, public children
{
public:
childlabourer(string name, int age) : worker(name),children(age)
{
cout << "childlabourer()" << endl;
}
~childlabourer()
{
cout << "~childlabourer()" << endl;
}
};
int main()
{
childlabourer *c = new childlabourer("Marry",20);
c->play();
c->work();
delete c;
c = NULL;
system("pause");
return 0;
}
4.3虚继承
当复杂关系中,既有多继承,也有多重继承时,就很麻烦,会有数据冗余。这时就可以采用虚继承(或者宏定义)
#ifndef XX.h
#define XX.H
...
#endif
巩固练习:定义Person人类,定义worker工人类及children儿童类,worker类中定义数据成员m_strName姓名,children类中定义数据成员m_iAge年龄,定义ChildLabourer童工类,公有继承工人类和儿童类,从而形成菱形继承关系。在main函数中通过new实例化ChildLabourer类的对象,并通过该对象的调用Person,worker及children类中的成员函数,最后销毁该对象,体会多重继承,多继承的继承特性,虚继承的定义方法
#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
class person
{
public:
person()
{
cout << "person" << endl;
}
~person()
{
cout << "~person" << endl;
}
void eat()
{
cout << "eat" << endl;
}
};
class worker:
virtual public person
{
public:
worker(string name)
{
m_strName = name;
cout << "worker()" << endl;
}
~worker()
{
cout << "~worker()" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
};
protected:
string m_strName;
};
class children:
virtual public person
{
public:
children(int age)
{
m_iAge = age;
cout << "children()" << endl;
}
~children()
{
cout << "~children()" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
};
protected:
int m_iAge;
};
class childlabourer :public worker, public children
{
public:
childlabourer(string name, int age) : worker(name),children(age)
{
cout << "childlabourer()" << endl;
}
~childlabourer()
{
cout << "~childlabourer()" << endl;
}
};
int main()
{
childlabourer *c = new childlabourer("Marry",20);
c->eat();
c->play();
c->work();
delete c;
c = NULL;
system("pause");
return 0;
}
5.C++远征--多态篇
面向对象的三大特征:封装,多态,继承。
5.1静态多态(早绑定),动态多态(晚绑定)
多态:指相同对象收到不同消息或不同对象收到相同消息时产生不同动作
5.1.1静态多态
如前面已经提到的内容,程序自己决定用哪个函数
class Rect
{
public:
int calcArea(int a);
int calcArea(int a,int b);
};
int main()
{
Rect rect;
rect.calcArea(10);
rect.calcArea(10,20);
renturn 0;
}
5.1.2动态多态(晚绑定)
要以封装和继承为基础
virtual 虚函数
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Shape.h"
#include"Rect.h"
#include"Circle.h"
using namespace std;
int main()
{
Shape *c1 = new Rect(3,6);
Shape *c2 = new Circle(3);
c1->calcArea();
c2->calcArea();
cout << c1->calcArea() << endl;
cout << c2->calcArea() << endl;
delete c1;
c1 = NULL;
delete c2;
c2 = NULL;
system("pause");
return 0;
}
Shape.h
#ifndef SHAPE_H
#define SHAPE_H // 宏定义,防止多继承过程中数据冗余报错
#include<iostream>
using namespace std;
class Shape
{
public:
Shape();
~Shape();
virtual double calcArea();
};
#endif
Shape.cpp
#include"Shape.h"
Shape::Shape()
{
cout << "Shape()" << endl;
}
Shape::~Shape()
{
cout << "~Shape()" << endl;
}
double Shape::calcArea()
{
cout << "Shape-calcArea()" << endl;
return 0;
}
Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include<iostream>
using namespace std;
#include"Shape.h"
class Circle: public Shape
{
public:
Circle(double r);
~Circle();
virtual double calcArea();
protected:
double m_dR;
};
#endif
Circle.cpp
#include"Circle.h"
Circle::Circle(double r)
{
m_dR = r;
cout << "Circle" << endl;
}
Circle::~Circle()
{
cout << "~Circle" << endl;
}
double Circle::calcArea()
{
cout << "Circle-calaArea" << endl;
return 3.14*m_dR*m_dR;
}
Rect.h
#ifndef RECT_H
#define RECT_H
#include<iostream>
#include"Shape.h"
using namespace std;
class Rect: public Shape
{
public:
Rect(double W, double H);
~Rect();
double calcArea();
protected:
double m_dW;
double m_dH;
};
#endif
Rect.cpp
#include"Rect.h"
Rect::Rect(double W, double H)
{
cout << "Rect" << endl;
m_dH = H;
m_dW = W;
}
Rect::~Rect()
{
cout << "~Rect" << endl;
}
double Rect::calcArea()
{
cout << "Rect--calcArea" << endl;
return m_dH*m_dW;
}
5.2虚析构函数 virtual ~Shape();
当父类指针指向子类时,delete时,通过父类释放内存时,只能释放父类的内存(只执行父类的析构函数),当通过子类释放内存时,父类子类的内存一起被删除(父类子类的析构函数都会被执行),这就造成了动态多态中的内存泄漏问题(内存泄漏指内存申请了却没有被释放)
virtual使用限制:
不能修饰普通函数。(virtual int text();)
不能修饰静态成员函数(virtual static int getCount();)
不能修饰内联函数(inline virtual int eat())
不能修饰构造函数(virtual Shape())