语言/CPP {函数重载,覆盖,重写函数override
,(非纯)虚函数,纯虚函数,抽象类,多态,多态类}
函数重载
定义
名字相同 但参数不同的 若干个函数;
.
比如void F(); void F(int);
都称为函数F
的重载;
性质
函数重载 跟继承无关, 全局函数可以是重载 同一个类的成员函数也可以是重载;
错误
void F(); int F();
这是编译错误; 返回值不同不是重载 (因为你调用F()
编译器不知道你要选择哪个呀…);
void F(); ? F(int);
是重载;
覆盖
定义
#覆盖{函数/变量}#
class Fa{
int D;
void F(){} // 不可以是*虚函数*;
};
class Son : Fa{
? D; // 类型任意(与父类D变量), 这属于*重写变量*;
? F( ?){} // 返回值|参数任意(与父类F函数无关), 这属于*重写函数*;
};
对于Son s
, 通过s.?
来访问子类的内容 通过s.Fa::?
来访问父类被覆盖的内容;
覆盖与函数重载, 很相像; 只不过函数重载是若干个同名函数 同时存在, 而覆盖是*把父类的内容给覆盖掉(也可以理解为是改为名字 加了个Fa::
的前缀 再在子类里写一个新的);
性质
覆盖 一定是与继承有关, 但与*多态(虚函数)*无关;
重写函数override
定义
子类对父类的虚函数的重写, 即带有virtual ? override{}
修饰的函数 称为重写函数;
(非纯)虚函数
定义
virtual void Fa::F(){ ...}
virtual void Son0::F() overide{ ...}
virtual void Son1::F() overide{ ...}
不管是父类还是子类 都需要实现; 只不过父类不用加override
关键字; 必须保证{返回值|参数}是完全一致的;
纯虚函数
定义
父类Fa
: virtual void F() = 0;
; 此时子类 如果没有重写(即实现void Son::F(){ ...}
)的话 则子类是个抽象类, 否则子类是多态类;
抽象类
定义
抽象类是: {包含纯虚函数的类; 父类有纯虚函数但当前类没有重写};
性质
抽象类 不可以申请对象, 在任何地方(不管是类内 还是类外) 执行T t; 或 new T
操作 都是编译错误的;
多态
定义
用以下代码 来表达多态的本质:
Fa * obj;
obj = new T; // `T`为`Fa/Fa的子类`;
obj->Func(); // 如果`Func`是虚函数, 则此时调用的是: `T`类对`Func虚函数`的实现版本;
即同一个指针Fa *
, 他所调用的虚函数的实现版本 可以在运行时动态的改变… (这就很神奇 你以为一个Fa *
的指针 肯定执行Fa::Func版本
不一定!);
@DELI;
性质
map<类名, map<变量名,QVariant> >
可以取代多态,比如多态类是Process, Process_Exe, Process_Edit, ...
那么就每个就对应map[ "Process_Exe"]
;
但他很不方便 因为你要频繁的做强转, 如果用多态类 比如struct Process_Exe{ int d1; double d2}
而用QVariant
的话 就是["Process_Exe"][ "d1"].toInt()
就很麻烦了;
多态类
定义
只要有虚函数的类(或父类有虚函数), 则该类是多态类 Polymorphic
;