c++动态绑定(多态)

c++多态(动态绑定)原理以及实现

  • 实现条件
  • 实现原理
  • 注意
    • 1.若是继承了多个虚函数但没有全部重写

实现条件

1.有继承关系的两个以及以上类,并且子类重写了父类的虚函数
2.用父类指针(引用)调用子类对象的虚函数(无法使用父类对象初始化子类实体,故而不能用子类指针调父类对象的虚函数。)

class base1{
public:
	virtual void func1(){	cout << "func1 of base1 class!"<<endl;	}
	virtual void func2(){	cout << "func2 of base1 class!"<<endl;	}
};

class child1 :public base1{
public:
	void func1(){	cout << "func1 of child1 class!"<<endl;	}
	void func2(){	cout << "func2 of child1 class!"<<endl;	}
	static const int a = 15;
};


int main(){
	base1 base1obj; child1 child1obj;
	base1 * p = &base1obj;
	p->func1();
	p = &child1obj;
	p->func1();

	getchar();
	return 0;
}

执行结果如下:
在这里插入图片描述

实现原理

编译器在第一次遇到虚函数时,会为该类自动分类一个虚函数表vftable和虚函数指针vfptr,其中vftable存放虚函数的二进制代码地址,vfptr指向该虚函数表。若后面还有虚函数,则往vftable后面添加新的二进制代码,但不会重新分配vfptr

在发生继承关系时,子类会把vfptr和vftable一同继承下来(在新的内存空间存放相同的内容),若是子类不重写虚函数,vfptr和vftable内容与父类完全一致。若是子类重写了虚函数,则子类虚函数表中被重写的虚函数会被覆盖,子类的vftable内容被修改。所以父类指针调用子类对象的虚函数时,可以找到子类自己的函数入口地址执行与父类同名函数不同的功能。
c++动态绑定(多态)_第1张图片
这要在运行时才能确定具体的函数入口地址,故称动态绑定。有多重继承关系或者多个子类继承同一个基类时,每个类都有自己的vfptr和vftable,在运行阶段动态找到不同的函数入口地址,用同一个指针的函数调用不同的函数功能,遂称多态

注意

1.若是继承了多个虚函数但没有全部重写

这种情况下子类的虚函数表中未被重写的虚函数二进制代码与父类完全一样,也可以被调用,执行父类的函数体;重写过的则执行子类重写后的函数体。
c++动态绑定(多态)_第2张图片

你可能感兴趣的:(C++)