純虛函式在乙個繼承結構中就是只有宣告沒有實現的函式。擁有純虛函式的類就叫做抽象類。
【舉個栗子】
class animal
//純虛函式
virtual void bark() = 0;
protected:
string _name;
};//以下是動物實體類
class cat :public animal
void bark()
};class dog :public animal
void bark()
};class pig :public animal
void bark()
};void bark(animal* p)
int main()
在上面這個animal類的作用就是:
string_name
:讓所有的動物實體類通過整合 animal直接復用該屬性
bark純虛函式
:在這裡面對於bark這個方法,在基類裡面因為不能明確是哪乙個動物,所以不能具體的寫對應的**,這時我們把bark寫成這樣子virtual void bark() = 0;這就是純虛函式。
抽象類不能例項化物件
:比如下面這個程式就不能呼叫成功,因為呼叫這個行為是調動不了的,因為這個行為沒有實現。所以抽象類只能當做指標或者引用來使用
int main()
練習:實現乙個汽車類的抽象來,來計算汽車剩餘油量還能跑的公里數
class car
//獲取汽車剩餘油量還能跑的公里數
double getleftmiles()
string getname()const
protected:
string _name;
double _oil;
virtual double getmilespergallon() = 0;//存虛函式 因為對於不同的車他每公里所用的油量是不同的
};class bnze : public car
double getmilespergallon()
};class audi : public car
double getmilespergallon()
};class bmw : public car
double getmilespergallon()
};//給外部提供乙個統一的獲取汽車剩餘路程數的api
void showcarleftmiles(car& car)
int main()
1、const_cast作用
:去掉(指標或者引用)常量屬性的型別轉換
【舉個栗子】
當我們想將乙個常量a的指標轉成乙個int*,在c語言中可以用如下的方式強制轉換。
int main()
但是在c++中,我們就有了const_cast,就可以使用如下的方式轉換:
int main()
總結:
上述兩種轉換在底層**成彙編指令過後)實現是一模一樣的
char* p = (char*)&a
是可以的,但是char* p2 = const_cast(&a)
是不可以的。因為,const_cast在提供強轉的時候,需要表示式(位址型別)與左邊定義的型別,包括要轉換的型別應該保持一致。防止了任意轉換型別導致一些不可預期的問題。
const_cast這裡面必須是指標或引用型別 int* int&**>
2、static_cast
作用
:提供編譯器認為安全的型別轉換(沒有任何聯絡的型別之間的轉換就被否定了),也是我們最常用的一種轉換方式。另外,基類型別和派生類型別之間也可以用static_cast轉換
。【舉個栗子】
下面這種方式編譯器就會直接報錯
int *p = nullptr;
short* b = static_cast(p);
3、reinterpret_cast他的作用就類似於c風格的強制型別轉換。你想要怎樣轉換都可。
4、dynamic_cast
作用
:用在繼承結構中,可以支援rtti型別識別的上下轉換
為了更好的解釋,我們還是以具體的栗子來加以說明。
【舉個栗子】
首先實現乙個鳥的抽象類
#includeclass bird
virtual void flyhigh() = 0;
protected:
std::string mname;
};class eagle:public bird
void flyhigh() };
class chicken:public bird
void flyhigh() };
int main()
現在我們要在這基礎上實現乙個函式能列印出所有鳥的飛行行為。
方式一:用模板實現
具體實現如下:
templatevoid showfly(bird_type* pb)
int main()
方式二:用基類指標實現因為允許所有的派生類物件用基類指標來指向,所以showfly函式還可以用以下的方式實現
void showfly(bird* pb)
改進:針對於不會飛的鳥進行特殊列印
我們可以通過以下兩種方式知道pb這個指標是指向的chiken派生類物件。
1、方式一:typeid
借用typeid這個關鍵字來動態獲取資訊。通過pb找到虛函式指標,再通過虛函式指標找到虛函式表,從虛函式表的第一項拿到rtti的資訊就可以確定這個物件本質是乙個什麼樣的型別。具體流程如下:
**實現如下:
void showfly(bird* pb)
else
}
2、方式二:使用dynamic_cast就是通過指標指向的物件找虛函式指標再通過虛函式指標找對應的虛函式表,從虛函式表中獲取rtti資訊。再拿這個資訊和你需要轉換的型別進行比較,如果兩個型別相同的話就是允許轉換的。這個時候就轉換成功。
具體實現如下:
void showfly(bird* pb)
else
}
多型 3 純虛函式和抽象類
2 純虛函式的語法 3 示例 純虛函式是乙個在基類中說明的虛函式,在基類中沒有定義,要求任何派生類都定義自己的版本。虛函式為個派生類提供乙個公共介面 介面的封裝和設計 軟體的模組功能劃分 乙個具有純虛函式的基類稱為抽象類,抽象類不能例項化。抽象類的子類必須要重寫父類中的純虛函式,否則也屬於抽象類。v...
多型,虛函式,純虛函式,抽象類
c 中,實現多型有以下方法 虛函式,抽象類,過載,覆蓋 多型性在object pascal和c 中都是通過虛函式 virtual function 實現的。這麼一大堆名詞,實際上就圍繞一件事展開,就是多型,其他三個名詞都是為實現c 的多型機制而提出的一些規則,下面分兩部分介紹,第一部分介紹 多型 第...
純虛函式和抽象類
純虛函式和抽象類 語法格式 virtual 返回值型別 函式名 引數 0 1 純虛函式沒有函式體,之有 宣告 0.只表示是純虛函式,2 0 不表示返回值是0,只是乙個形式,告訴編譯器這是純虛函式 3 包含純虛函式的類稱為抽象類 4 抽象類通常稱為基類,讓派生類去實現純虛函式。派生類必須實現純虛函式才...