1.重載是指允許存在多個同名函數,而這些函數的參數表不同(或許參數個數不同,或許參數類型不同,或許兩者都不同)。實現原理上:編譯器根據函數不同的參數表,對同名函數的名稱做修飾,然后這些同名函數就成了不同的函數(至少對于編譯器來說是這樣的)。如,有兩個同名函數:function func(p:integer):integer;和function func(p:string):integer;。那么編譯器做過修飾后的函數名稱可能是這樣的:int_func、str_func。對于這兩個函數的調用,在編譯器間就已經確定了,是靜態的。也就是說,它們的地址在編譯期就綁定了(早綁定),因此,重載和多態無關!
特征:
(1)相同的范圍(在同一個類中);
(2)函數名字相同;
(3)參數不同;
(4)virtual 關鍵字可有可無。
class A{
public:
void fun(int i);
void fun(double i);
void fun(int i, double j);
void fun(double i, int j);
int fun(int i); //錯誤,非重載
};
前四個為重載函數,最后一個不是
2.覆蓋(重寫)是指派生類函數覆蓋基類函數(是指子類重新定義父類虛函數的方法。)。 實現原理:和多態真正相關。當子類重新定義了父類的虛函數后,父類指針根據賦給它的不同的子類指針,動態的調用屬于子類的該函數,這樣的函數調用在編譯期間是無法確定的(調用的子類的虛函數的地址無法給出)。因此,這樣的函數地址是在運行期綁定的(晚綁定)。
特征:
(1)不同的范圍(分別位于派生類與基類);
(2)函數名字相同;
(3)參數相同;
(4)基類函數必須有virtual 關鍵字。
#include<iostream>
using namespace std;
class A
{
public:
virtual void test(int i)
{
cout<<”This is A::test()”<<i<<endl;
}
};
class B:public A
{
public:
virtual void test(char s)
{
cout<<”This is B:test()”<<s<<endl;
}
};
int main()
{
A a;
B b;
A * p=&a;
p->test(3);
p=&b;
p->test(‘c’);
return 0;
}
3.隱藏是指派生類的函數屏蔽了與其同名的基類函數,規則如下:
(1)如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數與基類的函數同名,并且參數也相同,但是基類函數沒有virtual 關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)
#include <iostream>
using namespace std;
class A
{
public:
void foo()
{
printf("1\n");
}
};
class B :public A
{
public:
void foo()
{
printf("3\n");
}
};
int main(void)
{
A a;
A *p_A = &a;
p_A->foo();//執行成員函數
B b;
B *p_B = &b;
p_B->foo();//執行成員函數
p_A = &b; //p_A指針執行子類,可以訪問被隱藏的基類成員函數
p_A->foo();
system("pause");
return 0;
}
輸出為1 3 1
隱藏和重寫,重載的區別:
#include<iostream>
using namespace std;
class A{
public:
void test1(int i, int j)
{
cout << "A::test1() : " << i << " " << j << endl;
}
void test1(int i)
{
cout << "A::test1() : " << i << endl; //重載
}
virtual void test2(int i)
{
cout << "A::test2(int) : " << i << endl;
}
};
class B : public A
{
public:
//隱藏
void test1(double i)
{
cout << "B::test1() : " << i << endl;
}
//重寫
void test2(int i)
{
cout << "B::test2(int) : " << i << endl;
}
//隱藏
void test2(double i)
{
cout << "B::test2(double) : " << i << endl;
}
};
int main()
{
B b;
A pa = &b;
B pb = &b;
pa->test2(3); //重寫,多態性,調用B的函數
b.test2(10); //隱藏,調用B的函數
pb->test2(20); //隱藏,調用B的函數
return 0;
}
輸出結果為:
B::test2(int) : 3
B::test2(int) : 10
B::test2(int) : 20
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。