1、继承
C++的访问控制方式有三种:public(公有继承)、protected(保护继承)和private(私有继承)。
C++派生类继承了基类的所有数据类型和除了构造函数和析构函数的所有成员函数。
基类的public | 基类的protected | 基类的private | |
公有继承 | public | protected | 不可访问 |
保护继承 | protected | protected | 不可访问 |
私有继承 | private | private | 不可访问 |
成员函数被重载的特征:
- 函数名相同
- 在同一个类体
- 参数个数或者类型不同
- virtual关键字可有可无
- 函数名相同
- 不同的类体(基类和派生类)
- 参数个数和类型必须相同
- 必须有virtual关键字
通过以下两个例子对比分析virtual关键字的作用
// Demo7_7.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
using namespace std;
class base0 {
public:
int var0 = 3;
void fun0() { cout << "var0 = " <<var0 << "\t member of base0 \t" <<&var0<<endl; }
};
class base1 :public base0 {
public:
int var1;
};
class base2 : public base0 {
public:
int var2;
};
class Derived :public base1, public base2 {
public:
int var;
void fun() { cout << "var = " << var << "\t\t member of Deriverd \t" <<&var<<endl; }
};
int main()
{
Derived d;
Derived *p = &d;
base0 b;
b.base0::var0 = 0;
b.base0::fun0();
d.base1::var1 = 1;
d.base1::fun0();
d.base2::var2 = 2;
d.base2::fun0();
d.var = 4;
d.fun();
b.base0::var0 = 5;
b.base0::fun0();
system("pause");
return 0;
}
运行结果:
程序结果分析:4个类(base0、base1、base2、Deriverd)各自保存了从类base0继承而来的成员数据和成员函数,即共有四个空间被占用,类base1、base2占用了不同的存储空间。
加上virtual关键字,把base0变为虚基类
// Demo7_7.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
using namespace std;
class base0 {
public:
int var0 = 3;
void fun0() { cout << "var0 = " <<var0 << "\t member of base0 \t" <<&var0<<endl; }
};
class base1 :virtual public base0 {
public:
int var1;
};
class base2 :virtual public base0 {
public:
int var2;
};
class Derived :public base1, public base2 {
public:
int var;
void fun() { cout << "var = " << var << "\t\t member of Deriverd \t" <<&var<<endl; }
};
int main()
{
Derived d;
Derived *p = &d;
base0 b;
b.base0::var0 = 0;
b.base0::fun0();
d.base1::var1 = 1;
d.base1::fun0();
d.base2::var2 = 2;
d.base2::fun0();
d.var = 4;
d.fun();
b.base0::var0 = 5;
b.base0::fun0();
system("pause");
return 0;
}
运行结果:
结果分析:
可以看到此时对类base1、base2成员的访问在同一地址,说明此时base1、base2共同使用同一空间,即对虚基类的继承,所有的类共同维护同一副本。此时共有三个副本,base0、base1和base2共同维护的一个副本和Deveried的副本。
总结:virtual关键字使继承虚基类的类共同维护同一副本,减少了程序对空间的开支,但是同时也减少了能够存储的数据量。