为什么虚函数在编译期间无法绑定?C++的多态为什么不在编译期完成,要在运行期完成

关于C++内部如何实现多态,对程序员来说即使不知道也没关系,但是如果你想加深对多态的理解,写出优秀的代码,那么这一节就具有重要的意义。 我们知道,函数调用实际上是执行函数体中的代码。函数体是内存中的一个代码段,函数名就表示该代码段的首地址,函数执行时就从这里开始。说得简单一点,就是必须要知道函数的入口地址,才能成功调用函数。

找到函数名对应的地址,然后将函数调用处用该地址替换,这称为函数绑定,或符号决议。

一般情况下,在编译期间(包括链接期间)就能完成符号决议,不用等到程序执行时再进行额外的操作,这称为静态绑定。如果编译期间不能完成符号决议,就必须在程序执行期间完成,这称为动态绑定。

非虚成员函数属于静态绑定:编译器在编译期间,根据指针(或对象)的类型完成了绑定。

而对于虚函数,知道指针的类型也无济于事。假设 func() 为虚函数,p 的类型为 A,那么 p->func() 可能调用 A 类的函数,也可能调用 B、C 类的函数,不能根据指针 p 的类型对函数重命名。也就是说,虚函数在编译期间无法绑定。

为什么虚函数在编译期间无法绑定?

因为我不知道运行期的状态啊

拿一个最简单的例子:

class BaseItem{
	public:
		virtual void itemMethod()=0;
};

class ItemA:BaseItem{};

class ItemB:BaseItem{};

class ItemC:BaseItem{};


////


while(nullptr != (rawData = readRawData())){

	BaseItem* pItem = nullptr;

	switch(rawData->head){
		case ItemTypeA:{
			pItem = new ItemA(rawData);
		}break;
		case ItemTypeB:{
			pItem = new ItemB(rawData);
		}break;
		case ItemTypeC:{
			pItem = new ItemC(rawData);
		}break;
		default:{}
	}

	if(nullptr != pItem){
		ItemCollection.insert(pItem);
	}
}
////////

for(auto it : ItemCollection){
	it->itemMethod();
}

很明显,我在编译期是无法得知容器中对象类型的,那么当我需要对容器中对象进行批量操作的时候,多态就是唯一的选择了。对于最后的for循环,无论你做什么,你都无法在编译期将其展开,只能在运行期根据实际的类型情况调用不同的函数。

猜你喜欢

转载自blog.csdn.net/qq_41786318/article/details/81979658