1. 程式人生 > >對C++ 虛擬函式的理解

對C++ 虛擬函式的理解

今天下午看一個開源專案的原始碼時候,碰到了虛擬函式。為此,就去查資料瞭解一下C++虛擬函式實現機制。

先上程式碼,對著程式碼講。

#include <iostream>
#include <stdio.h>

using namespace std;

class Animal
{
public:
	virtual void eat();   // eat 指定為虛擬函式 
	virtual void sleep();
	void work();   // work為非虛擬函式 
	void run();
};

class Dog: public Animal
{
public:
	void eat();
	void work();
};

void Animal::eat()
{
	cout << "Aminal eats something" << endl;
}

void Animal::sleep()
{
	cout << "Animal is sleeping" << endl;
}
void Animal::work()
{
	cout << "Animal works hardly" << endl;
}

void Animal::run()
{
	cout << "Aminal is running" << endl;
}

void Dog::eat()
{
	cout << "Dog eats bone" << endl;
}

void Dog::work()
{
	cout << "Dog works hardly" << endl;
}

int main()
{
	Animal* ani = new Dog();
	ani -> eat();
	ani -> sleep();
	ani -> work();
	
	return 0;
}

程式中定義兩個類:基類Animal和派生類Dog,也即是父類Animal和子類Dog。

該程式的函式被分為四類:

1.eat函式是虛擬函式,被重新定義

2.sleep函式是虛擬函式,未被重新定義

3.work函式是普通函式,被重寫

4.run函式是普通函式,未被被重寫。

編譯器處理虛擬函式的方法是,對每個類新增一個隱藏成員:一個虛擬函式表(virtual function table, vtbl)。這裡將會建立兩個虛擬函式表。虛擬函式表裡面存放的是每個類中虛擬函式的地址,注意這裡,只存放虛擬函式的地址,不會存放其他成員函式。

程式會使用Dog型別的虛擬地址表,所以,這裡,eat函式會執行子類的eat函式,而sleep仍然會執行父類的sleep函式。而work函式會執行指標的型別,也就是Animal型別。

也就是,對於父類指標指向子類物件的情況來說,除了被重新定義的虛擬函式(eat函式)會執行子類的函式(子類eat函式)之外,其他所有型別的函式都將執行父類函式。

執行結果如下:

Dog eats bone
Animal is sleeping
Animal works hardly
Aminal is running

--------------------------------
Process exited after 0.2431 seconds with return value 0
請按任意鍵繼續. . .

那如果想執行子類Dog的work函式怎麼辦?

強制型別轉換!

將main函式改寫如下:

int main()
{
	Animal* ani = new Dog();
	ani -> eat();
	ani -> sleep();
	ani -> work();
	ani -> run();
	
	cout << endl;
	
	((Dog*) ani) -> eat();
	((Dog*) ani) -> sleep();
	((Dog*) ani) -> work();
        ((Dog*) ani) -> run();
	
	return 0;
}

執行結果如下:

Dog eats bone
Animal is sleeping
Animal works hardly
Aminal is running

Dog eats bone
Animal is sleeping
Dog works hardly
Aminal is running

--------------------------------
Process exited after 0.1338 seconds with return value 0
請按任意鍵繼續. . .

這時候,就和普通的繼承一摸一樣了,哦不是,一模(mu)一樣。

參考:

1. C++ Prime Plus 第六版(中文版)

2.JAVA的多型用幾句話能直觀的解釋一下嗎? - 程式狗的回答 - 知乎 https://www.zhihu.com/question/30082151/answer/120520568