據我所知,覆寫是指您有 2 個具有相同名稱和函式回傳型別(void, int, float.. 等)以及相同引數編號和型別的函式。
多載是當您有 2 個具有相同名稱但引數編號/型別或函式回傳型別應該不同的函式時。
但是今天上課的時候,看到了這張幻燈片:
這不應該是超載嗎?不覆寫?因為這里的回傳型別改變了(從void
到float),基類中的 fa1() 函式沒有引數,但在派生類中它有浮點引數。
如果這是壓倒性的,為什么?
uj5u.com熱心網友回復:
在 C 中,派生類中的任何方法只有在它們的宣告匹配時才會覆寫基類中的方法(我說“匹配”,但我不知道它的正式術語)。也就是說,所有引數必須具有相同的型別,并且const限定this必須相同。如果有任何不匹配,派生類中的方法會隱藏所有具有相同名稱的方法,而不是覆寫。這就是您圖片中的“錯誤”試圖告訴您的。因此// overrides,該圖片中的評論不正確且具有誤導性。
是的,許多 C 老師實際上并不了解這些有些晦澀的細節。
順便說一句,如果你想重寫,你的基類中的方法應該是virtual; 否則,多型將不起作用。如果不是virtual,我們也說派生類方法隱藏了基類方法。然而,這里關于隱藏的部分幾乎沒有任何意義;這個詞真正想表達的是你不是壓倒性的。
此外,正如您所注意到的,多載是存在多個名稱相同但簽名不同的方法。它們都應該出現在派生類中才有用 - 如果派生類只有一個方法fa1,而另一個fa1在基類中,它們將被隱藏。但是,有語法糖可以將所有內容fa1從基礎“復制”到派生,從而禁用所有隱藏語意:
class A
{
public:
void fa1();
void fa1(int);
};
class B: public A
{
public:
using A::fa1;
void fa1(int, int);
};
...
B b;
b.fa1(); // calls A::fa1()
b.fa1(4); // calls A::fa1(int)
b.fa1(4, 8); // calls B::fa1(int, int)
關于隱藏的部分很少(如果有的話)有用。覆寫時,您應該告訴編譯器 - 為此使用override關鍵字。然后編譯器將檢查您的代碼是否按預期作業。
class A
{
public:
virtual void fa1(int) {}
void fa2(int) {}
};
class B: public A
{
public:
void fa1(int) override {} // OK
void fa1() override {} // ERROR: doesn't really override - different signature
void fa2(int) override {} // ERROR: doesn't really override - not virtual in base
};
uj5u.com熱心網友回復:
ia1不超載。首先,您不能多載變數。所以ia1絕對是一個覆寫。而且這也是一件很危險的事情。在我公司,我們的編碼標準不允許在任何情況下覆寫變數名稱。它只會導致混亂。
fa1不過——這看起來像是超載。基類fa1()不帶引數,但子類版本帶浮點數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/364598.html
下一篇:我可以洗掉下一行代碼嗎?
