[英]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
類型,因為沒有必要。
所以,總結一下:
fun
來查找一個名為fun
in int
的函數,因為基指針的fun
函數接受一個int
。 在Base
找到版本,因為沒有oerride。 fun
來查找一個名為fun
的函數,從Derived
開始,它會找到你的覆蓋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.