1. 程式人生 > >C++類型別成員函式的過載、覆蓋與隱藏

C++類型別成員函式的過載、覆蓋與隱藏

類層次中的同名成員函式,有3種關係:過載overload,覆蓋override和隱藏oversee,hide。

1.成員過載

只有在同一個類中定義的同名成員函式才存在過載關係,主要特點是函式的引數和數目不同,但不能是引數的個數和型別均相同,僅僅依靠返回值的不同來區分函式,和普通的函式過載是一樣的,另外,過載和成員函式是否是虛擬函式無關。

class A{//下面都是過載關係的函式
	...
	virtual int fun();
	void fun(int);
	void fun(double,double);
	static int fun(char);
	...
};
成員過載函式的特徵:
  • 位於同一個類中
  • 相同的函式名字
  • 不同的引數列表
  • virtual關鍵字可有可無

2.成員函式的覆蓋

覆蓋是指在派生類和基類中的同名函式,但是基類函式必須是虛擬函式。主要特徵是
  • 分別位於基類和派生類中
  • 有相同的函式名字
  • 相同的引數,引數個數和型別
  • 基類函式必須是虛擬函式,virtual
class A{
	public:
	virtual void func1(int,int){}
	
};
class B:public A{
	public:
	void func1(int,int ){}
};
與上面過載的區別是
  • 覆蓋是子類與父類之間的關係,是垂直關係;而過載是同一個類中不同的方法之間的關係,是水平關係。
  • 覆蓋要求的是引數列表相同,過載則要求引數列表不同;覆蓋要求返回型別相同,過載無要求。

  • 覆蓋關係中,呼叫方法是根據物件的型別來決定的,過載關係是根據呼叫的實參表和形參表來選擇方法的。

3.成員函式的隱藏

隱藏指的是在某些情況下,派生類中的函式遮蔽了基類中的同名函式。分為下面 兩種情況 1)兩個函式的引數相同,但是基類函式不是虛擬函式,和覆蓋的區別是基類是否是虛擬函式
class A{
	public:
	void fun(int xp){
		cout<<xp<<endl;
	}
};
class B:public A{
	public:
	void fun(int xp){//將隱藏父類的fun函式
		...
	}
};
上面若想呼叫基類的同名函式,則需要加上域名進行指定
B b;
b.A::fun(2);
2)兩個函式的引數不同,無論基類 函式是不是虛擬函式,基類函式都會被遮蔽,和過載的區別是兩個函式是不是在同一個類中。
class A{
	public:
	virtual void fun(int xp){
		cout<<xp<<endl;
	}
};
class B:public A{
	public:
	void fun(char* xp){//將隱藏父類的fun函式
		...
	}
};
由於派生類中基類的同名成員函式被隱藏,所以呼叫的時候可能會出現問題。如果呼叫的是基類的成員函式則要進行域名指定