多态:
1.静态多态:是在编译器的编译期间完成的,编译器会根据实际参数类型来选择调用合适的函数
-函数重载
-泛型编程
2.动态多态:在运行期间,根据基类的引用和指针指向的对象来确定具体应该调用哪一个虚函数
-虚函数
一定要注意,在不构成多态的情况下,base* b=new Derived;此时b指向的是派生类中的基类部分。
-overload(重载):名称完全相同、参数(类型或者个数)不相同的函数
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
-override(覆盖):用来实现C++多态性的,子类重新改写父类声明为virtual的函数
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数列表完全相同;
(4)基类函数必须有virtual 关键字。
(5) 访问限定符可以不同
-overwrite(改写):派生类的函数屏蔽(或者称之为“隐藏”)了与其同名的基类函数
(1)如果派生类的函数与基类的函数同名,但是参数不同。那么此时,不论有无virtual关键字,基类的函数将被隐藏。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。那么此时,基类的函数被隐藏。
基类中定义的virtual虚函数,在继承子类中同名函数自动都属于虚函数,可以不需要virtual关键字。
多态的原理:
假设Base* b=new Base();通过sizeof(b)可以发现,基类的虚函数指针和成员变量存储在一起,指向虚函数表。就是通过虚函数表找到的虚函数入口。(见类的存储)
对于派生类:
1.先将基类的虚函数表中的内容拷贝一份
2.如果派生类中对基类中的虚函数进行重写,使用派生类的虚函数替换相同偏移量位置的基类虚函数
3.如果派生类中新增自己的虚函数,按照其在派生类中的声明次序,放在上述虚函数之后
类的存储
类只是将数据成员保存在一起。用隐含的A * const p指针来作为this指针调用成员函数。
1.如何计算一个类的大小
class A1
{
public:
void f1()
{}
void f2()
{}
};
class A2
{
public:
void f1()
{}
private:
int a = 10;
};
class A3
{};
int main()
{
cout << sizeof(A1) << endl; //1
cout << sizeof(A2) << endl; //4
cout << sizeof(A3) << endl; //1
return 0;
}
一个类的大小,实际上就是该类中非静态成员变量之和, 同时也要注意内存对齐,空类大小为1(在linux和VS下是1)