继承语法:
class 派生类名 : 访问修饰符 基类名1, …, 访问修饰符 基类名n
{
成员变量和成员函数
};
访问修饰符: public、protected 或 private,则默认为 private。
public:在类的内部、外部都能使用
protected:在类的内部使用,在继承的子类中使用
private:只能在类的内部,不能在类的外部(包括继承中的子类也不能使用)
(派生类private继承,可以访问基类的函数无法访问成员)
一个派生类继承了所有的基类方法,但下列情况除外:
基类的构造函数、析构函数和拷贝构造函数。
基类的重载运算符。
基类的友元函数。
继承的作用:
- 子类拥有父类的所有成员变量和成员函数
- 子类可以拥有父类没有的方法和属性
- 子类就是一种特殊的父类
- 子类对象可以当作父类对象使用
继承中的构造析构调用原则
1、子类对象在创建时会首先调用父类的构造函数
2、父类构造函数执行结束后,执行子类的构造函数
3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
4、析构函数调用的先后顺序与构造函数相反
继承中的同名成员变量处理方法
- 当子类成员变量与父类成员变量同名时,子类依然从父类继承同名成员
- 同名成员存储在内存中的不同位置
- 在子类中通过作用域分辨符::进行同名成员区分
总结:同名成员变量和成员函数通过作用域分辨符进行区分
继承的各种情况
- 不带虚函数的单继承
#include "stdafx.h"
#include "iostream"
using namespace std;
class baseClass
{
public:
baseClass (int a = 1) : base(a){}
void fun0(){cout << base << endl;}
int base;
};
class inheritClass : public baseClass
{
public:
inheritClass (int a = 2):derive(a){}
void fun1(){cout << base << endl;}
int derive;
};
int _tmain(int argc, _TCHAR* argv[])
{
inheritClass a;
return 0;
}
基类和派生类内存中的分布:
2. 不带虚函数的多继承
#include "stdafx.h"
#include "iostream"
using namespace std;
class baseClass_01
{
public:
baseClass_01 (int a = 1) : base01(a){}
void fun0(){cout << base01 << endl;}
int base01;
};
class baseClass_02
{
public:
baseClass_02 (int a = 3):base02(a){}
void fun2(){cout << base02 << endl;}
int base02;
};
class inheritClass : public baseClass_01,public baseClass_02
{
public:
inheritClass (int a = 2):derive(a){}
void fun1(){cout << derive << endl;}
int derive;
};
int _tmain(int argc, _TCHAR* argv[])
{
inheritClass a(10);
baseClass_01 *pb01 = &a;
baseClass_02 *pb02 = &a;
inheritClass* p1 = &a;
cout << "p1 = " << p1 << "\t pb01 = " << pb01 << "\t pb02 = " << pb02 << endl;
return 0;
}
代码运行
基类和派生类之间转换时会自动寻找起始地址
3. 不带虚函数的菱形继承
#include "stdafx.h"
#include "iostream"
using namespace std;
class Base
{
public:
Base (int a = 1):base(a){}
void fun0(){cout << base << endl;}
int base;
};
class baseClass_01 : public Base
{
public:
baseClass_01 (int a = 1) : base01(a){}
void fun0(){cout << base01 << endl;}
int base01;
};
class baseClass_02 : public Base
{
public:
baseClass_02 (int a = 3):base02(a){}
void fun2(){cout << base02 << endl;}
int base02;
};
class inheritClass : public baseClass_01,public baseClass_02
{
public:
inheritClass (int a = 2):derive(a){}
void fun1(){cout << derive << endl;}
int derive;
};
int _tmain(int argc, _TCHAR* argv[])
{
inheritClass a(10);
//Base *b = &a; 存在二义性,无法准确确定基类的地址
baseClass_01 *pb01 = &a;
baseClass_02 *pb02 = &a;
inheritClass* p1 = &a;
cout << " p1 = " << p1 << "\t pb01 = " << pb01 << "\t pb02 = " << pb02 << endl;
return 0;
}
无法将派生类的地址转换成基类Base的地址。由于派生类中存在两个Base基类所以程序无法确定具体哪个地址才是需要的
【结论】
简单继承(不存在虚函数和虚继承)时,派生类是基类叠加之后的产物。
- 带虚函数的单继承
#include "stdafx.h"
#include "iostream"
using namespace std;
class baseClass
{
private:
int i;
char c;
public:
virtual void virt_fun1(){ cout << "baseClass virt_fun1" << endl; }
virtual void virt_fun2(){ cout << "baseClass virt_fun2" << endl; }
void comm_fun1(){ cout << "baseClass comm_fun1" << endl; }
void comm_fun2(){ cout << "baseClass comm_fun2" << endl; }
};
class inheritClass : public baseClass
{
private:
char c;
public:
virtual void virt_fun2(){ cout << "inheritClass virt_fun1" << endl; }
virtual void virt_fun3(){ cout << "inheritClass virt_fun2" << endl; }
void comm_fun1(){ cout << "inheritClass comm_fun1" << endl; }
void comm_fun3(){ cout << "inheritClass comm_fun3" << endl; }
};
int _tmain()
{
inheritClass a;
a.virt_fun1();
cout << "------------------------------" << endl;
baseClass *b = new inheritClass();
b->virt_fun1();
b->virt_fun2(); //虚函数,基类指针调用派生类的同名虚函数
b->comm_fun1(); //普通函数,基类指针调用基类的普通类函数
cout << "------------------------------" << endl;
inheritClass *c = (inheritClass*)b;
c->virt_fun1();
c->comm_fun1();
c->comm_fun2();
c->comm_fun3();
cout << "------------------------------" << endl;
cout << " b = " << b << "\n c = " << c << endl;
return 0;
}
【结论】
不管派生类有没有虚函数,基类存在虚函数时派生类中多了一个vfptr(虚函数)指针
派生类和基类存在同名的虚函数时,派生类的虚函数会覆盖基类的同名函数
对于普通同名函数(非虚函数),基类和 派生类分别调用自己的函数
基类有虚函数时,派生类的虚指针位于基类中。派生类中新增的虚函数,追加到第一个基类的虚函数表的后面
- 带虚函数的多继承
#include "stdafx.h"
#include "iostream"
using namespace std;
class baseClass_01
{
private:
int i;
char c;
public:
virtual void virt_fun1(){ cout << "baseClass_01 virt_fun1" << endl; }
virtual void virt_fun2(){ cout << "baseClass_01 virt_fun2" << endl; }
void comm_fun1(){ cout << "baseClass_01 comm_fun1" << endl; }
void comm_fun2(){ cout << "baseClass_01 comm_fun2" << endl; }
};
class baseClass_02
{
private:
int i;
char c;
public:
virtual void virt_fun2(){ cout << "baseClass_02 virt_fun2" << endl; }
virtual void virt_fun3(){ cout << "baseClass_02 virt_fun3" << endl; }
void comm_fun2(){ cout << "baseClass_02 comm_fun2" << endl; }
void comm_fun3(){ cout << "baseClass_02 comm_fun3" << endl; }
};
class inheritClass : public baseClass_01, public baseClass_02
{
private:
char c;
public:
virtual void virt_fun2(){ cout << "inheritClass virt_fun2" << endl; }
virtual void virt_fun3(){ cout << "inheritClass virt_fun3" << endl; }
virtual void virt_fun4(){ cout << "inheritClass virt_fun4" << endl; }
void comm_fun2(){ cout << "inheritClass comm_fun2" << endl; }
void comm_fun3(){ cout << "inheritClass comm_fun3" << endl; }
};
int _tmain()
{
inheritClass a;
a.virt_fun1();
cout << "------------------------------" << endl;
baseClass_01 *b01 = &a;
b01->virt_fun1();
b01->virt_fun2();
b01->comm_fun1();
cout << "------------------------------" << endl;
baseClass_02 *b02 = &a;
b02->virt_fun2();
b02->virt_fun3();
b02->comm_fun2();
cout << "------------------------------" << endl;
inheritClass *c = (inheritClass*)b01;
c->virt_fun1();
c->comm_fun1();
c->comm_fun2();
c->comm_fun3();
cout << "------------------------------" << endl;
// inheritClass *c = (inheritClass*)b02; 多继承时,是所有基类都能转换成派生类的
cout << " &a = " << &a << "\n b01 = " << b01 << "\n b02 = " << b02 << "\n c = " << c << endl;
return 0;
}
6. 带虚函数的菱形继承
#include "stdafx.h"
#include "iostream"
using namespace std;
class Base
{
public:
Base (int a = 1):base(a){}
virtual void fun0(){cout << base << endl;}
int base;
};
class baseClass_01 : public Base
{
private:
int i;
char c;
public:
virtual void virt_fun1(){ cout << "baseClass_01 virt_fun1" << endl; }
virtual void virt_fun2(){ cout << "baseClass_01 virt_fun2" << endl; }
void comm_fun1(){ cout << "baseClass_01 comm_fun1" << endl; }
void comm_fun2(){ cout << "baseClass_01 comm_fun2" << endl; }
};
class baseClass_02 : public Base
{
private:
int i;
char c;
public:
virtual void virt_fun2(){ cout << "baseClass_02 virt_fun2" << endl; }
virtual void virt_fun3(){ cout << "baseClass_02 virt_fun3" << endl; }
void comm_fun2(){ cout << "baseClass_02 comm_fun2" << endl; }
void comm_fun3(){ cout << "baseClass_02 comm_fun3" << endl; }
};
class inheritClass : public baseClass_01, public baseClass_02
{
private:
char c;
public:
virtual void virt_fun2(){ cout << "inheritClass virt_fun2" << endl; }
virtual void virt_fun3(){ cout << "inheritClass virt_fun3" << endl; }
virtual void virt_fun4(){ cout << "inheritClass virt_fun4" << endl; }
void comm_fun2(){ cout << "inheritClass comm_fun2" << endl; }
void comm_fun3(){ cout << "inheritClass comm_fun3" << endl; }
};
int _tmain()
{
inheritClass a;
a.virt_fun1();
cout << "------------------------------" << endl;
baseClass_01 *b01 = &a;
b01->virt_fun1();
b01->virt_fun2();
b01->comm_fun1();
cout << "------------------------------" << endl;
baseClass_02 *b02 = &a;
b02->virt_fun2();
b02->virt_fun3();
b02->comm_fun2();
cout << "------------------------------" << endl;
inheritClass *c = (inheritClass*)b01;
c->virt_fun1();
c->comm_fun1();
c->comm_fun2();
c->comm_fun3();
cout << "------------------------------" << endl;
// inheritClass *c = (inheritClass*)b02; 多继承时,是所有基类都能转换成派生类的
cout << " &a = " << &a << "\n b01 = " << b01 << "\n b02 = " << b02 << "\n c = " << c << endl;
return 0;
}