
正文
C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
函数重写:(在子类中重写父类中的函数)
父类中被重写的函数 依然会继承 给子类。
子类中重写的函数将覆盖父类中的函数。
通过作用域分辨符 :: 可以访问到父类中的函数。
例如:
#include <iostream>
#include <string> using namespace std; class parent
{
public:
void parent_func(int i , int j)
{
cout << "parent_func(int i , int j)"<<i<<','<<j<<endl;
}
}; class subClass : public parent
{
public:
void parent_func(int i , int j)//重写父类中的 void parent_func(int i , int j)
{
cout << "parent_func(int i , int j)"<<i*<<','<<j*<<endl;
}
}; void doPrint(parent *p)//如果是 subClass 声明的对象,将把 subClass类退化为 parent类来处理(C++ 默认)
{
p->parent_func(, );
}
int main()
{
parent p;
subClass s; s.parent::parent_func(,);//使用作用域分辨符 通过subClass 声明的对象 去调用parent类中的 parent_func(int i , int j)函数 doPrint(&p);//使用 parent类对象
doPrint(&s);//使用subClass类对象
}
运行结果:
parent_func(int i , int j),
parent_func(int i , int j),
parent_func(int i , int j),
面向对象期望的行为:
根据实际的对象类型判断如何调用重写函数。
父类指针(引用)指向
父类对象则调用父类中定义的函数
子类对象则调用 子类中 重写 的函数
也就是说期望 void doPrint(parent *p) 这个函数调用的时候,如果是父类的对象则直接调用父类中的 void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)1,2
如果是子类对象 则调用void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)2,4
就需要在 父类中将void parent_func(int i , int j) 改为:virtual void parent_func(int i , int j) 表明此函数为 虚函数 子类通过继承的关系 也将把void parent_func(int i , int j) 修改为 虚函数
-通过virtual 支持多态(C++ 中实现多态的唯一方法)
-被virtual 声明的函数被重写后具备多态的特性
-被virtual 关键字声明的函数叫做虚函数。
修改代码如下:
#include <iostream>
#include <string> using namespace std; class parent
{
public:
virtual void parent_func(int i , int j)
{
cout << "parent parent_func(int i , int j)"<<i<<','<<j<<endl;
}
}; class subClass : public parent
{
public:
void parent_func(int i ,int j)//重写父类中的 void parent_func(int i , int j)
{
cout << "subClass parent_func(int i , int j)"<<i*<<','<<j*<<endl;
}
}; void doPrint(parent *p)
{
p->parent_func(, ); //根据对象类型判断如何调用重写函数。
}
int main()
{
parent p;
subClass s; doPrint(&p);//使用 parent类对象
doPrint(&s);//使用subClass类对象
}
运行结果:
parent parent_func(int i , int j),
subClass parent_func(int i , int j),
多态存在的意义:
-多态在程序运行的过程中展现。
-函数重写必须实现多态,否则无意义
-是面向对象 组件化程序设计 的基础特性
静态联编:
在编译的期间就确定了具体的函数调用(重载函数)
动态联编:
在程序运行后才能确定函数的调用(重写函数)
例如:
#include <iostream>
#include <string> using namespace std; class parent
{
public:
virtual void func(int i )
{
cout << "func(int i )"<<i<<endl;
}
virtual void func(int i , int j)
{
cout << "parent func(int i , int j)"<<i<<','<<j<<endl;
}
virtual void func(int i , int j,int k)
{
cout << "parent func(int i , int j,int k)"<<i<<','<<j<<','<<'k'<<endl;
}
}; class subClass : public parent
{
public:
void func(int i , int j) //等价于 virtual void func(int i , int j)
{
cout << "subClass func(int i , int j)"<<i+j<<endl;
}
void func()
{
cout <<" void func()"<<endl;
}
}; void doPrint(parent *p)
{
p->func(, ); //实现多态特性
}
int main()
{
parent p;
subClass s; p.func();//静态联编
p.func(,);//静态联编
p.func(,,);//静态联编 cout <<endl;
s.func(,);//静态联编 编译时就知道了调用函数,最终会调用到,subClass 类中的 void func(int i , int j) 函数 doPrint(&p);//展现动态联编
doPrint(&s);//展现动态联编
}
运行结果:
func(int i )
parent func(int i , int j),
parent func(int i , int j,int k),,k subClass func(int i , int j)
parent func(int i , int j),
subClass func(int i , int j)







