1. 程式人生 > >虛擬函式與派生類過載

虛擬函式與派生類過載

虛擬函式很簡單,之前轉載了人家的一片不錯的文章就是關於虛擬函式的

這裡不講虛擬函式的定義了

直接進入主題,就是過載。

如果基類聲明瞭一個函式是虛擬函式,而且派生類並沒有改變引數,只是把函式內容改變了,那麼這個可以認為是“重寫 “

派生類過載是什麼呢,就是在派生類中僅僅保留基類的函式名,引數變了,或者返回型別也變了,如果不改變引數僅僅改變返回型別不是過載,這樣也是錯的。

如果過載了,你就不會得到基類對應的函式名的函數了,被隱藏了!

除非你使用基類作用域解析符號,要不你呼叫基類版本就是錯誤的!

看例子:


class   C0
{
public:
virtual void   Set1(int   i)
{
cout <<"C0:Set1   i=" <<i <<endl;
}
/****found*****/
virtual   void   Set2(int   i)
{
cout <<"C0:Set2   i=" <<i <<endl;
}
};


class   C1:public   C0
{
public:
int   Set1(string i)
{
cout <<"C1:Set1   i=" <<i <<endl;
return 9;
}


void   Set2(int   i)
{
cout <<"C1:Set2   i=" <<i <<endl;
    C0::Set2(i);

}
};


void   main()
{
C0   *p;
C1   obj2;

obj2.Set1(1);  //這裡就出錯了
obj2.Set2(2);
/*******found*****/
p   =   &obj2;

p-> Set1(3);
p-> Set2(4);

return;
}

上面指示的地方就出錯了,因為派生類的過載直接隱藏了基類的函式,而且繼承作用暫時失效,如果你要使用基類的方法就是這樣:obj2.C0::Set1(1);  加上作用域解析符。

有人問:p-> Set1(3);這裡為什麼不出錯啊,c1類裡面沒有這麼個函式型別啊,很簡單,虛擬函式只對基類裡面定義了的才算,不能理解成基類裡面一個定義了,其他的也變成了虛擬的了,這樣是不對的。

這裡就有一個建議,如果過載了基類的函式,最好是把基類的虛擬函式都重寫在派生類裡面一次,就不會隱藏基類的函式方法了