![](/img/trans.png)
[英]pure virtual functions overloading and covariant return types with multiple inheritance
[英]Overloading Virtual Functions with same arguments and different return types
我有以下代碼,編譯時沒有任何錯誤或警告。
#include<iostream>
using namespace std;
class Father
{
public:
int foo()
{
cout<<"int foo";
return 111;
}
};
class Son: public Father
{
public:
long foo()
{
cout<<"long foo";
return 222;
}
};
int main()
{
Son x;
long n;
n=x.foo();
cout<<"\nn is "<<n;
return 0;
}
輸出如下所示。
long foo
n is 222
我想函數foo()
在派生類Son
被重寫,並且沒有重載,因為以下程序給了我錯誤。
using namespace std;
class Father
{
public:
int foo()
{
cout<<"int foo";
return 111;
}
long foo()
{
cout<<"long foo";
return 222;
}
};
int main()
{
Father x;
long n;
n=x.foo();
cout<<"\nn is "<<n;
}
錯誤消息如下所示。
error: 'long int Father::foo()' cannot be overloaded
error: with 'int Father::foo()'
兩種結果都符合預期,因為當兩個函數的區別僅在於返回類型時,則發生覆蓋而不是重載。 但是,當我在第一個程序中將函數foo()
聲明為virtual
函數時,出現錯誤,並且無法理解原因。 我違反了什么規則? 該程序如下所示,
#include<iostream>
using namespace std;
class Father
{
public:
virtual int foo()
{
cout<<"int foo";
return 111;
}
};
class Son: public Father
{
public:
long foo()
{
cout<<"long foo";
return 222;
}
};
int main()
{
Son x;
long n;
n=x.foo();
cout<<"\nn is "<<n;
}
錯誤消息如下所示,
error: conflicting return type specified for 'virtual long int Son::foo()'
error: overriding 'virtual int Father::foo()'
除了在Father
類中將函數foo()
聲明為virtual
,我沒有做任何更改。 然后突然出現了第一個程序中沒有的沖突。 我無法理解這一點。
有什么建議么? 謝謝。
您不能通過更改返回類型,僅通過更改函數的參數類型/數量(或添加const修飾符,以及可能的其他幾種方式)來重載。 在派生類中進行編譯時會編譯的原因是,派生類本質上是從基類中隱藏了一個。
請參考返回類型的函數重載? 關於為什么基於返回類型的重載/重載會成為問題。
當成員函數不是虛函數時,在派生類中具有相同名稱的函數不會覆蓋基類中的函數,至少在通常情況下不會如此。 派生類函數僅隱藏基類函數。 例如,如果您有如下代碼:
Son s;
Father &f = s;
f.foo();
然后將調用Father::foo()
,如果Father::foo()
不是虛擬的,則不會調用Son::foo()
。
由於Son::foo()
沒有覆蓋Father::foo()
,因此沒有特殊要求返回類型必須匹配。 但是,一旦將Father::foo()
虛擬化,則Son::foo()
會覆蓋Father::foo()
,因此返回類型需要達成協議。
此外,當您具有不同的參數類型而不是不同的返回類型時,就會發生重載。 在同一個作用域中聲明兩個具有相同名稱而僅在返回類型上有所不同的函數是完全非法的。
虛假函數的返回提示與基類不同,派生函數的返回函數從標准允許,並稱為協變函數。
但是,某些約束適用於返回類型。 基本上,如果它返回一個指向類的指針或引用,則可以定義一個協變函數。 在這種情況下,基類必須返回由其子級返回的指向該類的直接或間接祖先的指針或引用。
例如,可以在此處找到參考。
第一個示例程序采用了覆蓋的概念,因此將調用派生類中定義的函數。在虛擬示例程序中,如果在基類中將某個函數聲明為虛函數,則需要在派生類中使用該函數具有與基類虛函數相同的簽名。在這種情況下,派生類中的函數類型有所不同,因此會產生錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.