簡體   English   中英

該功能是否覆蓋基本功能?

[英]Does the function override the base function?

我有三個不同的編譯器,我用來編譯這段代碼。 其中一個(我最信任的那個)警告Derived中的函數隱藏了Base中的函數。 其他編譯器(一個是Visual C ++ )沒有警告。 如果我啟用/ Wall或/ W4,Visual C ++甚至不會發出警告。

我傾向於認為這是編譯器中的一個錯誤,它會發出警告,因為它編譯代碼。 如果它確實沒有覆蓋基函數,那么當我創建派生模板的實例時它應該給出錯誤。

任何人都可以確認這應該如何表現?

struct Base
{
   virtual void Func(float f) = 0;
};

template <typename T>
struct Derived : Base
{
   virtual void Func(T f){}
};

int main()
{
   Derived<float> d;
   d.Func(0);
   return 0;
}

當使用float實例化Derived ,我會收到意外警告。 當使用int實例化Derived ,我會收到錯誤,如預期的那樣。

它確實被覆蓋了。 您可以使用override關鍵字在C ++ 11中輕松說服自己,如果不覆蓋該函數,則不允許編譯代碼:

struct Base
{
   virtual void Func(float f) = 0;
   virtual ~Base() = default; // to silence warnings
};

template <typename T>
struct Derived : Base
{
   void Func(T f) override {} // will fail to compile if not overriding
};

int main()
{
   Derived<float> d;
   d.Func(0);
   return 0;
}

這里有實例。

請注意,在預C ++ 11中,您可以通過在派生類中更改其簽名來意外隱藏virtual基本函數,因此即使您將派生函數標記為virtual代碼仍然編譯,但不再具有多態性,請參閱此類這里的例子。 不幸的是,即使使用-Wall -Wextra ,g ++也不會提供任何警告。 這就是為什么override是一種在編譯時實際執行真正覆蓋的更安全的方法。

我不相信你應該得到警告。
這與:

struct Derived : Base
{
  virtual void Func(float f) { };
};

當您的模板參數為float

沒有隱藏,只有抽象函數的實現。

在此上下文中,隱藏函數的警告讓我們知道派生類中的成員函數具有相同的名稱,但簽名不同於基類中的函數。 考慮:

struct Base
{
    void foo(int) {}
    void bar(int) {}
};

struct Derived: Base
{
    void bar(int, int) {}
};

int main()
{
    Derived d;
    d.foo(1);
    d.bar(1); // will not compile: Base::bar is hidden by Derived::bar
}

在這個例子中,目的可能是添加一個名為“bar”的附加函數,但結果是一旦找到帶有名為bar的函數的作用域,編譯器就停止查找帶有函數名稱bar的新作用域。 因此bar(int)被bar(int,int)(或具有不匹配簽名的任何其他欄)隱藏。 (或者在非虛擬情況下,即使函數匹配。)

在這個Graznarak的代碼中,Base :: Func隱藏在Derived實例化為任何非浮點(或浮點const)的T值的情況下。

Graznarak詢問正確的行為。 生成的代碼的正確之前沒有問題Derived :: Func()被調用。

但這留下了一個問題:警告是否合適。 標准沒有答案。 它從不表達是否應該產生警告的意見。 是否警告特定問題總是主觀的,編制者可以通過在這方面表現出良好的判斷來區分自己。

那么你的編譯器應該警告這種情況嗎? 可以說,編寫的代碼可以完成預期的操作。 但是模板的存在意味着它將在多個類型上實例化(否則為什么要制作模板),對於任何其他類型,隱藏會發生。 因此,有人可能會爭辯說,應該在創建派生模板時給出警告。 但是人們也可以爭辯說,在指定非浮點類型實例化之前不應該發出警告。

爭論前者是警告會更早,並且可能由程序員編寫有問題的代碼來檢測。 爭論后者是在實例化非浮點類型之前,沒有可疑情況需要警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM