[英]Overloaded functions(virtual/non virtual)
我有4個重載函數vfoo
(3個是virtual)
我試圖在這里測試一些概念:
#include<iostream>
using namespace std;
/*Base class having 4 overloaded function*/
class ClassBaseV
{
public:
virtual void vfoo( int x ) {
cout << "ClassBaseV vfoo(int), x = " << x << endl;
}
virtual void vfoo( double x ) {
cout << "ClassBaseV vfoo(double), x = " << x << endl;
}
virtual void vfoo( int x, double y ) {
cout << "ClassBaseV vfoo(int,double), x = " << x << ", y = " << y << endl;
}
void vfoo( double x, int y ) {
cout << "ClassBaseV vfoo(double,int), x = " << x << ", y = " << y << endl;
}
};
class ClassDerived1 : public ClassBaseV
{
public:
//Overloaded with char x
void vfoo( char x ) {
cout << "ClassDerived1 vfoo(char), x = " << x << endl;
}
//over riding int x
void vfoo( int x ) {
cout << "ClassDerived1 vfoo(int), x = " << x << endl;
}
};
int main()
{
ClassBaseV *cB = new ClassDerived1(); /*Base pointer storing derived class object*/
ClassDerived1 *cd1 = new ClassDerived1(); //Derived class object
cd1->vfoo('a');//Direct call using derived class object. this works
char a = 'a';
cB->vfoo(a); // trying to call char x using cB. This calls derived class int How?
cB->vfoo(10); // trying to call int x using CB. This calls derived class int
cB->vfoo(2.2); // Wanted this to not to work as base class overloaded functions are hidden but this works
return 1;
}
第一個問題:
cB->vfoo(a);
當您在此處調用vfoo時,它將嘗試在ClassBaseV中找到vfoo(char x)的定義,但是沒有找到,但是仍然找到可以隱式轉換為的vfoo(int x)的定義,因此它將調用此方法。從ClassBaseV。
編譯器將嘗試獲取作為類型提供的類的方法的定義。
ClassBaseV *cB = new ClassDerived1();
在此行上,鍵入cB作為指向ClassBaseV的指針。 從現在開始,編譯器不能在子類中查找方法定義的缺點,但是仍然可以這樣做,因為ClassBaseV知道對父類的任何可能的繼承。
第二個問題:
cB->vfoo(2.2);
在這行上,您調用方法vfoo(double x),因為ClassBaseV中提供了對double的轉換,並且您沒有在ClassDerived1中覆蓋此方法。
因此,通常調用該方法的ClassBaseV實現。
如果要調用ClassDerived1中重寫的vfoo之一,則必須將其強制轉換為int或char(以及寬松的信息)
cB->vfoo(static_cast<int>(2.2));
或在ClassDerived1中添加一個新方法,以覆蓋ClassBaseV中的vfoo(double x)。
另外,如果要強制ClassDerived1實現ClassBaseV中的方法vfoo(double x),則必須將其聲明為純virtual:
virtual void vfoo( double x ) = 0;
如果您在派生類中重寫一部分重載,通常的做法是using
聲明將所有未重寫的函數放到作用域中。 防止尷尬的失敗。
cB->vfoo(a); // trying to call char x using cB. This calls derived class int How?
Base中的重載分辨率最接近匹配(char-> int)並使用虛擬調度進行調用
cB->vfoo(10); // trying to call int x using CB. This calls derived class int
在ovrload解析中進行匹配匹配並派生虛擬分派。
cB->vfoo(2.2); // Wanted this to not to work as base class overloaded functions are hidden but
精確匹配重載解決方案,虛擬派發至基地。
切勿嘗試刪除派生類中的功能。
接口繼承意味着:我最多需要保證基本需求,並且我的行為符合基本合同。
“當基類指針存儲派生類對象時的行為是什么” -這是多態性的核心思想。 多態性基於特定的行為,該行為基於運行時確定的對象類型,而重載函數則在編譯時解決。
常量文字的類型可以很容易地在編譯時確定10
為int
, 2.2
為double
,這將確定將使用哪個成員函數。 然后,實例的類型將確定將使用哪個實現(哪個類)。 這是更簡單的示例:
class Animal {
public:
virtual void makeSound(){ std::cout << "hi" << std::endl; }
virtual void makeSound(int pain){ std::cout << "ouch" << std::endl; }
virtual void makeSound(double d){ std::cout << "aaaaaaaargh" << std::endl; }
};
class Cat : public Animal {
public:
virtual void makeSound(){ std::cout << "meow" << std::endl; }
virtual void makeSound(int pain){ std::cout << "MEEEEEOW!!!" << std::endl; }
virtual void makeSound(double d){ std::cout << "meow double" << std::endl; }
};
int main() {
Animal *a = new Animal();
Animal *cat = new Cat();
a->makeSound();
cat->makeSound();
a->makeSound(100);
cat->makeSound(100);
cat->makeSound(750.80);
}
輸出:
你好
喵
哎喲
EE !!!
喵喵
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.