1. 程式人生 > >過載,重定義與隱藏

過載,重定義與隱藏

過載:在同一個類中,要求函式名相同,函式引數不同

重定義:在基類與派生類之間,派生類重新定義基類中的函式,且要求函式的名稱、引數型別以及返回值型別完全一致。如果基類中的函式為virtual,則通過基類指標指向派生類時,可以實現多型。如果是非virtual,通過基類指標,不論指向的是基類還是派生類,所呼叫的都是基類的函式;通過派生類指標,呼叫的則是派生類的函式。(即實際呼叫的函式由指標的靜態型別決定,即指標定義為什麼型別,其靜態型別就是什麼型別)

隱藏:在基類和派生類之間,派生類定義了基類中的同名函式,但是引數可以不同。當引數不同的時候,對於派生類物件、指標、引用,其基類該同名函式都被隱藏了。(在virtual情況下,屬於重定義)

class Base
{
public:
	void f()
	{cout<<"Base:f"<<endl;}
	void f(int a)
	{cout<<"Base:f(int)"<<endl;}
	virtual void g()
	{cout<<"Base:g()"<<endl;}
	virtual void h()
	{cout<<"Base:h()"<<endl;}

};
class Derived:public Base
{
public:
	void f(float)
	{cout<<"Derived:f(float)"<<endl;}
	void f(int)
	{cout<<"Derived:f(int)"<<endl;}
	void g(int)
	{cout<<"Derived:g(int)"<<endl;}
	void h()
	{cout<<"Derived:h()"<<endl;}
};
int main()
{
	Base *p1,*p2;
	Derived *d1;
	Base b;Derived d;
	p1=&b;
	p2=&d;
	d1=&d;
	p1->f(2);//指標的靜態型別為Base,直接呼叫Base中的f(int)
	p2->f(2);//指標的靜態型別為Base,直接呼叫Base中的f(int)
	p2->f(2.222);//將2.222轉換為了int,指標的靜態型別為Base,直接呼叫Base中的f(int)
	p2->g();//指標的靜態型別為Base,直接呼叫Base中的g(),因為在Derived中並沒有重新定義g(),所以虛擬函式表中,指向的函式Base中的g()
	p2->h();//指標的靜態型別為Base,直接呼叫Base中的h(),但這時候虛擬函式表中的h()已經替換成了Derived中的h()
	//d1->f();//編譯不通過,Derived中沒有無參的f
	d1->f(2);//指標的靜態型別為Derived,直接呼叫Derived中的f(int)
	//d1->g();//編譯不通過,Derived中沒有無參的g
	d1->g(2);//指標的靜態型別為Derived,直接呼叫Derived中的g(int)
	cout<<"****************"<<endl;
	d1=(Derived*)p1;
	d1->h();//動態函式由所指物件決定
	d1->f(2);//靜態函式由指標的靜態型別決定
	d1=(Derived*)p2;
	d1->f(2);
	p1=d1;
	p1->f(2);

	return 0;
}