2013-02-25 79 views
5

返回類型是否影響函數覆蓋? (據我所知返回typde不是一個函數/方法簽名的一部分) 在一個基類我有一個功能,它並沒有得到論據,返回int是純虛函數。在每個派生類中,我定義了返回類型的枚舉。該函數在派生類中被覆蓋,即它具有相同的簽名但行爲不同。 問題是:這是合法的重寫和返回類型不是功能覆蓋的一部分?函數覆蓋不同的返回類型

代碼示例:

class Base 
{ 
    public: 
    typedef int ret; 
    virtual ret method() = 0; 
}; 

class Der1 
{ 
public: 
    enum ret1{ 
    ret1_0, 
    ret1_1 
    }; 
    ret1 method() { return ret1_1;} 
}; 

class Der1 
{ 
public: 
    enum ret2{ 
    ret2_0, 
    ret2_1 
    }; 
    ret1 method() { return ret2_0;} 
}; 
+0

@LihO - 謝謝您的留言。這是一個錯字 – Yakov 2013-02-25 09:59:30

回答

4

您可以覆蓋功能與不同的返回類型,但只有協變返回類型是允許的。

功能重寫意味着要麼基類的方法或派生類的方法將在運行時間根據由所述指針所指向的實際對象上被調用。
它意味着:
即:每一個地方的基類方法可以稱爲地方都可以通過調用派生類的方法來代替沒有任何變化,以調用代碼。

爲了達到此目的,唯一可能的方法是限制重寫虛擬方法的返回類型以返回與Base類或從該類派生的類型(共變量返回類型)相同的類型,因此標準強制執行此條件。

如果沒有這個條件的現有代碼將通過增加新的功能(新首要功能)打破。

+0

您的協變鏈接已損壞 – 2017-01-19 17:54:38

1

你有什麼不是重寫。

C++支持協變返回類型原始指針和原料引用。

但這就是全部。

1

我們不應該通過重寫它改變在基類的函數的返回類型。不建議通過隱藏基本成員來改變返回類型,因爲它會導致奇怪的結果,不能以多態的方式使用。

4

簡短的回答:不,這是不允許的或更好的把它不重寫,但是重寫,即你是不是覆蓋Base::method()但是創建具有相同名稱的新方法。大多數編譯器會警告你。有了您的示例代碼,但假設Base::method純虛,考慮一下:

void callMethod(Base const& b) 
{ 
    auto a1 = b.method(); //what should the type of a1 be? -> it's int. Every time. 
    std::cout << a1 << '\n'; 
} 

int main() 
{ 
    Der1 d1; 
    auto a2 = d1.method(); //a2 is ret1_1 of type ret1 
    callMethod(d1);  //calls Base::method and prints that int, not Der1::method 
} 

你是返回類型並不是函數簽名的一部分權WRT。但是在壓倒虛擬功能時,簽名並不重要。 §10.3,7明確規定:

壓倒一切的函數的返回類型應是相同 重寫的函數的返回類型或協變與 類的功能。如果函數D::f覆蓋功能 B::f,返回類型的函數是協變,如果他們滿足 以下標準:

- 兩者都是對類指針,無一不是班 左值引用,或兩者都是右值引用到 類

- 在B::f返回類型的類是相同的類 中的D::f返回類型的類,或者是一個明確的和 訪問的直接或間接的基類的類在返回 類型的D::f

- 兩個指針或引用具有相同的 CV-資格和在D::f返回類型的類類型具有 相同的CV-資格或更少的CV-資格比類類型 返回類型B::f

+0

+1 – ThomasMcLeod 2014-10-10 14:24:49

相關問題