1. 程式人生 > >函式的過載、重寫、重定義

函式的過載、重寫、重定義

函式過載(overload)

函式過載是指在一個類中宣告多個名稱相同但引數列表不同的函式,這些的引數可能個數或順序,型別不同,但是不能靠返回型別來判斷。特徵是:
(1)相同的範圍(在同一個作用域中);
(2)函式名字相同;
(3)引數不同;
(4)virtual 關鍵字可有可無(注:函式過載與有無virtual修飾無關);
(5)返回值可以不同;


函式重寫(也稱為覆蓋 override)

函式重寫是指子類重新定義基類的虛擬函式。特徵是:

(1)不在同一個作用域(分別位於派生類與基類);
(2)函式名字相同;
(3)引數相同;
(4)基類函式必須有 virtual 關鍵字,不能有 static 。
(5)返回值相同,否則報錯;
(6)重寫函式的訪問修飾符可以不同;

過載與覆蓋的區別:

(1)覆蓋是子類和父類之間的關係,是垂直關係;過載是同一個類中不同方法之間的關係,是水平關係;

(2)覆蓋要求引數列表相同,過載要求引數列表不同;覆蓋要求返回型別相同,過載則不要求;

(3)覆蓋關係中,呼叫方法體是根據物件的型別(基類型別還是派生類型別)來決定的,過載關係是根據呼叫時的實參表與形參表來選擇方法體的。


重定義(也稱隱藏)

(1)不在同一個作用域(分別位於派生類與基類) ;
(2)函式名字相同;
(3)返回值可以不同;
(4)引數不同。此時,不論有無 virtual 關鍵字,基類的函式將被隱藏(注意別與過載以及覆蓋混淆);

(5)引數相同,但是基類函式沒有 virtual關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆);

程式碼舉例

#include <iostream>
using namespace std;

class Base
{
public:
	void a()
	{
		cout << "void Base::a()" << endl;
	}
	//過載了上面的void a()函式,發生在同一個類中
	void a(int i)
	{
		cout << "void Base::a(int i)" << endl;
	}
	virtual void b()
	{
		cout << "virtual void Base::b()" << endl;
	}
	virtual void c()
	{
		cout << "virtual void Base::c()" << endl;
	}
	virtual void d()
	{
		cout << "virtual void Base::d()" << endl;
	}
private:
	int x;
};
class Derived :public Base {
public:
	//在基類Base中,函式a不是虛擬函式,所以這裡是重定義
	void a()
	{
		cout << "void Derived::a()" << endl;
	}
	//引數不同。此時,不論無論有無virtual 關鍵字,基類的函式將被隱藏,屬於重定義
	void b(float f)
	{
		cout << "virtual void Derived::b(float f)" << endl;
	}
	/*
	//編譯器報錯,也就是說編譯器認為函式名和引數都與基類的虛擬函式c相同,那麼返回值也必須相同
	//要麼,你就別讓編譯期認為這是多型,也就是別和基類設定一樣的函式名或引數,改變其一即可
	float c()
	{
		cout << "virtual float Derived::c()" << endl;
		return 1.1;
	}
	*/
	//父類中定義了虛擬函式,子類與父類函式名字相同,引數相同,返回值相同,屬於函式重寫
	void d()
	{
		cout << "virtual void Derived::d()" << endl;
	}
};
int main()
{
	int i = 6;
	float f = 'a';
	Base base;
	base.a();
	base.a(i);
	base.b();
	base.c();
	base.d();
	Derived derived;
	derived.a();
	derived.b(f);
	derived.d();
	system("pause");
	return 0;
}