簡體   English   中英

虛擬功能的重載

[英]Overloading of virtual functions

我在接受采訪時被問到這個問題。 我無法在那里回答這個問題。 我現在也無法得到它,為什么輸出是這樣的。 這是代碼:

#include <iostream>
using namespace std;

class Base
{
public:
    virtual void fun ( int x = 0)
    {
        cout << "Base::fun(), x = " << x << endl;
    }
};

class Derived : public Base
{
public:
    virtual void fun ( float x = 10.0 )
    {
        cout << "Derived::fun(), x = " << x << endl;
    }
};


int main()
{
    Derived d1;
    Base *bp = &d1;
    bp->fun();
    d1.fun();
    d1.fun(1.2);
    return 0;
}

上面代碼的輸出是:

Base::fun(), x = 0
Derived::fun(), x = 10
Derived::fun(), x = 1.2

問題是:在第一種情況下,我們說fun()函數都被重載(並且因為它們的聲明不同而沒有被覆蓋)並且基本fun()被調用,但是這些聲明的聲明是不可能的( )重載(因為它們只是聲明是否包含默認參數)

void fun(int x = 0)
void fun(float x = 10.0)

這些功能不可能過載。

上述兩種情況似乎都存在矛盾。

任何解釋這種情況的相關文章/鏈接都會非常有幫助。

在C ++中,對於覆蓋基類函數的成員函數,參數類型必須與基類函數的參數類型完全匹配。 由於基類函數接受一個int而派生類的函數接受一個float ,因此它不被視為重寫。 您可以使用override關鍵字來查看:

class Base
{
public:
    virtual void fun ( int x = 0)
    {
        cout << "Base::fun(), x = " << x << endl;
    }
};

class Derived : public Base
{
public:
    virtual void fun ( float x = 10.0 ) override // Doesn't compile!
    {
        cout << "Derived::fun(), x = " << x << endl;
    }
};

你的代碼中發生的事情是C ++認為你的函數是一個重載 (另一個具有相同名稱的函數)而不是覆蓋 我們來看看這段代碼:

Derived d1;
Base *bp = &d1;
bp->fun();

這里,由於行bp->fun()使用通過基類指針的調用,C ++在Base查找以查看要調用的函數。 它找到Base::fun(int) 現在,由於該函數被標記為virtual ,它將調用Base::fun(int)除非它覆蓋了它。 但由於沒有覆蓋, Base::fun(int)最終會被調用。

那么后來這兩行呢?

d1.fun();
d1.fun(1.2);

在這里,由於您在靜態類型Derived對象上調用這些函數,C ++嘗試在Derived類中查找名為fun的函數。 它找到你的新函數Derived::fun(float) ,並且由於C ++在類中進行名稱查找的方式,它不會在基類中查找Base::fun(int) 因此,這兩個調用都被視為對Derived::fun(float)調用,因此沒有關於在沒有參數的情況下調用哪個函數的歧義。 編譯器甚至從未查看Base類型,因為沒有必要。

所以,總結一下:

  • 你引入了一個重載 ,而不是重寫 使用override關鍵字可以幫助您將來診斷此類問題。
  • 通過基指針調用fun來查找一個名為fun in int的函數,因為基指針的fun函數接受一個int Base找到版本,因為沒有oerride。
  • 通過派生對象調用fun來查找一個名為fun的函數,從Derived開始,它會找到你的覆蓋。

暫無
暫無

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

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