对象类型
静态类型:对象声明的类型,是在编译时确定的
对象类型
动态类型:目前所指对象的类型,是在运行时确定
多态类型
多态是指c++中同样的消息被不同类型的对象接收时导致的不同行为,消息指的是对象的成员函数的调用,不同行为就是调用不同的函数。
函数重载
静态多态
泛型编程
多态
动态多态 虚函数
静态多态
#include <iostream>
using namespace std;
int Add(int a,int b)
{
return (a+b);
}
double Add(double a,double b)
{
return(a+b);
}
int main()
{
cout<<Add(1,2)<<endl;
cout<<Add(1.2,1.3)<<endl;
system("pause");
return 0;
}
静态多态是在编译期间完成的,编译器根据函数实参的类型推断要调用的函数,如果有对应的函数就调用,没有就出现编译错误
动态多态
动态多态是在执行期间判断所引用对象的实际类型,根据其实际类型调用相应的方法。
#include <iostream>
using namespace std;
class Base
{
public:
virtual void FunTest1(int nTest){cout<<"Base::FunTest1()"<<endl;}
void FunTest2(int nTest){cout<<"Base::FunTest2()"<<endl;}
virtual void FunTest3(int nTest){cout<<"Base::FunTest3()"<<endl;}
virtual void FunTest4(int nTest){cout<<"Base::FunTest4()"<<endl;}
};
class Derived:public Base
{
public:
virtual void FunTest1(int nTest){cout<<"Derived::FunTest1()"<<endl;}
virtual void FunTest2(int nTest){cout<<"Derived::FunTest2()"<<endl;}
void FunTest3(int nTest){cout<<"Derived::FunTest3()"<<endl;}
virtual void FunTest4(int nTest1,int nTest2){cout<<"Derived::FunTest4()"<<endl;}
};
int main()
{
Base *pBase=new Derived;
pBase->FunTest1(0);
pBase->FunTest2(0);
pBase->FunTest3(0);
pBase->FunTest4(0);
//pBase->FunTest4(0,0);
system("pause");
return 0;
}
第一个打印派生类函数体内容,因为在funtest1在基类里为虚函数,在派生类里对其进行重写
第二个打印的是基类函数体内容,因为funtest2基类里未写为虚函数
第三个打印的是派生类函数体内容,因为funtest3在基类里为虚函数,在派生类里重写时省略virtual关键字
第四个打印的事基类函数体内容,因为funtest4在派生类里未重写。
动态绑定的条件:
- 派生类必须重写基类的虚函数
- 通过基类指针或引用调用基类的虚函数(该虚函数派生类必须要重写)
重载、重写(覆盖)、重定义(隐蔽)的区别
重载即为上面add函数,重写即为funtest1,funtest3,重定义为funtest2(派生类里也不加virtual)
注意的是:
- 派生类重写基类虚函数实现多态,要求函数名、参数列表、返回值完全相同。特殊地,协变:函数返回值不同,基类返回基类对象的引用,派生类返回派生对象的引用。
- 基类中定义虚函数,其派生类中该函数始终保持虚函数特性。
- 只有类的非静态成员函数才能定义为虚函数,静态成员函数不能定义为虚函数。
- 如果在类外定义虚函数,只能在声明函数时加virtual关键字,定义时不用加。
- 构造函数不能定义为虚函数,虽然可以将operator=定义为虚函数,但最好不要这么做,使用时容易混淆
- 不要在构造函数和析构函数中调用虚函数,在构造函数和析构函数中,对象是不完整的,可能会出现未定义的行为。
- 最好将基类的析构函数声明为虚函数。(析构函数比较特殊,因为派生类的析构函数跟基类的析构 函数名称不一样,但是构成覆盖,这里编译器做了特殊处理)
注意项摘自:https://blog.youkuaiyun.com/eagle_1036077338/article/details/53186171
该论文里还详细叙述了虚表的概念,建议空闲的时间多学习一下