父类和子类的函数调用
1.用指针(引用)调用函数的时候,被调用的函数取决于指针(引用)的类型;
2.涉及多态性时,采用虚函数和动态绑定,函数调用在运行时绑定,而非在编译时绑定,此时不再单独根据指针(引用)类型来判断调用的函数,而是根据对象中虚指针指向的虚表中的函数地址来确定调用的函数。
3.构造函数不可以是虚函数,析构函数可以是虚函数;当父类的构造函数非虚,则删除指向子类的父类指针时,只会调用父类析构函数,而父类析构函数为虚时,会调用父类的析构函数,在调用子类的析构函数。
4.使用new操作的指针,必须使用delete手动删除
I . 父类析构函数为虚函数时
#include <stdio.h>
#include <string.h>
using namespace std;
class father{
public :
father()
{
printf("father class father()\n");
}
virtual ~father() //此时的father析构函数为虚函数
{
printf("father class ~father()\n");
}
void fun()
{
printf("father class fun()\n");
}
void fun1()
{
printf("father class fun1()\n");
}
virtual void fun2()
{
printf("father class virtual fun2()\n");
}
virtual void fun3()
{
printf("father class virtual fun3()\n");
}
};
class son :public father{
public :
son()
{
printf("son class son()\n");
}
~son() //子类为虚函数或者非虚没有关系
{
printf("son class ~son()\n");
}
void fun()
{
printf("son class fun()\n");
}
void fun2()
{
printf("son class virtual fun2()\n");
}
};
cpp文件:
#include "father.h"
using namespace std;
int main(int argc,char *argv[])
{
father *father_prt=new son();
father_prt->fun(); //普通成员函数,按指针类型调用
father_prt->fun1(); //普通成员函数,按指针类型调用
father_prt->fun2(); //虚函数 ,按实际指向对象调用
father_prt->fun3(); //虚函数,但是子类没有实现,则调用父类的虚函数
son *son_prt = new son();
son_prt->fun(); //普通成员函数,按指针类型调用
son_prt->fun1(); //普通成员函数,按指针类型调用,但是子类没有实现,因此向上调用父类的实现函数
son_prt->fun2(); //虚函数 ,按实际指向对象调用
son_prt->fun3(); //虚函数,但是子类没有实现,则调用父类的虚函数
delete father_prt;
printf("==========================\n");
delete son_prt;
}
运行结果:
II.父类函数为非虚时的运行结果:
III .未使用delete 删除 father_prt,son_prt时的运行结果: