多態
1、概念
多態是c++的特徵之一
多態的分類:靜態多態(靜態聯編)、動態多態(動態聯編)
靜態多態(靜態聯編):函數入口地址 是在 編譯階段 確定(運算符重載、函數重載)
動態多態(動態聯編):函數入口地址 是在 運行階段 確定(虛函數)
2、引入
class Animal
{
public:
void sleep(void)
{
cout<<"animal 動物在睡覺"<<endl;
}
};
class Cat:public Animal
{
public:
void sleep(void)
{
cout<<"Cat 貓在睡覺!! 喵喵"<<endl;
}
};
void test01()
{
//用基類(指針或引用) 保存 子類對象(向上轉換)
Animal *p = new Cat;
p->sleep();//調用的是基類的sleep
Cat cat;
Animal &ob = cat;
ob.sleep();//調用的是基類的sleep
//怎麼調用子類的sleep呢?
}
運行結果:
總結:基類指針、引用 只能訪問 子類對象中 基類部分 數據
3、使用基類指針、引用 訪問 子類對象中的成員方法(虛函數)
使用virtual修飾成員函數 該成員函數就是虛函數。
class Animal
{
public:
//虛函數
virtual void sleep(void)
{
cout<<"animal 動物在睡覺"<<endl;
}
};
vfptr虛函數指針 指向的是虛函數表(vftable)
vftable表存放的是 vfptr做保存的函數入口地址
注意://如果 Animal沒有涉及到繼承 函數指針變量 就指向自身sleep
class Animal
{
public:
//虛函數 本質 是一個函數指針變量
virtual void sleep(void)
{
cout<<"animal 動物在睡覺"<<endl;
}
};
void test01()
{
//如果 Animal沒有涉及到繼承 函數指針變量 就指向自身sleep
Animal ob;
ob.sleep();
}
運行結果:
4、擁有虛函數的類 涉及得到繼承
class Animal
{
public:
//虛函數 本質 是一個函數指針變量
virtual void sleep(void)
{
cout<<"animal 動物在睡覺"<<endl;
}
};
class Cat:public Animal
{
public:
virtual void sleep(void)
{
cout<<"貓在睡覺!!喵喵"<<endl;
}
};
void test01()
{
Animal *p = new Cat;
p->sleep();//調用的是cat中sleep
}
運行結果:
總結:
當虛函數涉及到繼承的時候 子類 會繼承 父類的(虛函數指針vfptr 虛函數表vftable),編譯器會將虛函數表中的函數入口地址 更新 成子類的 同名(返回值、參數都相同)的函數入口地址。
如果基類指針、引用 訪問虛函數的時候 就會 間接的調用 子類的虛函數.
5、虛函數的應用案例(基類指針、引用 作爲函數的參數)
#include <iostream>
using namespace std;
class Base
{
public:
virtual void sleep(void)
{
cout<<"父親在睡覺"<<endl;
}
};
class Son1:public Base
{
public:
void sleep(void)
{
cout<<"Son1在安靜的睡覺"<<endl;
}
};
class Son2:public Base
{
public:
virtual void sleep(void)
{
cout<<"Son2在輕度的睡覺"<<endl;
}
};
class Son3:public Base
{
public:
virtual void sleep(void)
{
cout<<"Son3在雨聲般的睡覺"<<endl;
}
};
class Son4:public Base
{
public:
virtual void sleep(void)
{
cout<<"Son4在鼾聲如雷"<<endl;
}
};
//以基類指針作爲函數的參數 函數可以操作該基類派生出的任意子類對象
void sleepFun(Base &ob)
{
ob.sleep();
}
int main(int argc, char *argv[])
{
Son1 ob1;
Son2 ob2;
Son3 ob3;
Son4 ob4;
sleepFun(ob1);
sleepFun(ob2);
sleepFun(ob3);
sleepFun(ob4);
return 0;
}
#千鋒教育#
人活着就要快樂。
運行結果:
多態涉及到 易考的面試題:
問題:C++的動態捆綁機制是怎麼樣的?
首先,我們看看編譯器如何處理虛函數。當編譯器發現我們的類中有虛函數的時候,編譯器會創建一張虛函數表,把虛函數的函數入口地址放到虛函數表中,並且在類中祕密增加一個指針,這個指針就是vpointer(縮寫vptr),這個指針是指向對象的虛函數表。在多態調用的時候,根據vptr指針,找到虛函數表來實現動態綁定。
各位看官,感覺我寫的怎麼樣呢, 大家有沒有看懂呢, 歡迎評論
如果對大家有幫助,不要忘記點個贊哦.