一、概述
C++中的多態性是指同一個函數可以有多種不同的實現方式,並且在運行時根據實際情況進行選擇執行。在C++中實現多態有兩種方式:靜態多態和動態多態。靜態多態是指在編譯時確定函數的實現,包括函數重載和模板函數;動態多態是指在運行時根據對象的實際類型來確定函數的實現,包括虛函數和抽象類。
二、靜態多態
1、函數重載
函數重載是指在同一個作用域中定義多個同名函數,它們的參數列表不同。編譯器會根據函數的參數列表唯一地確定要調用的函數。函數重載的實現可以通過編譯時的函數匹配來實現,實現起來比較簡單。
下面是一個函數重載的示例代碼:
#include <iostream> void print(int i) { std::cout << "This is an integer: " << i << std::endl; } void print(float f) { std::cout << "This is a float: " << f << std::endl; } int main() { print(42); print(3.14f); return 0; }
上面的代碼中,我們定義了兩個同名的函數`print`,但是它們的參數列表不同,一個接受整數,一個接受浮點數。在調用函數`print`時,編譯器會自動根據參數的類型選擇調用哪個函數。
2、模板函數
模板函數是指在定義函數時使用了類型參數,可以讓函數適用於多種不同的類型。編譯器會在編譯時根據參數類型來生成具體的函數實現。模板函數的實現可以通過編譯時的模板實例化來實現。
下面是一個模板函數的示例代碼:
#include <iostream> #include <cstdlib> template <typename T> T max(T a, T b) { return a > b ? a : b; } int main() { int x = 42, y = 23; float f = 3.14f, g = 2.71f; std::cout << "Max of " << x << " and " << y << " is " << max(x, y) << std::endl; std::cout << "Max of " << f << " and " << g << " is " << max(f, g) << std::endl; return 0; }
上面的代碼中,我們定義了一個模板函數`max`,它可以針對整數、浮點數等多種類型進行運算。在調用函數`max`時,編譯器會根據參數類型自動推斷出要使用哪個具體的函數實現。
三、動態多態
1、虛函數
虛函數是指在基類中定義的函數可以被派生類重寫的函數。通過將函數聲明為虛函數,我們可以在運行時根據對象的實際類型來確定要調用的函數實現。在C++中,只要將函數聲明為虛函數即可實現動態多態。
下面是一個虛函數的示例代碼:
#include <iostream> class Shape { public: virtual float calculateArea() { return 0; } }; class Square : public Shape { public: Square(float l) : _length(l) {} virtual float calculateArea() { return _length * _length; } private: float _length; }; class Circle : public Shape { public: Circle(float r) : _radius(r) {} virtual float calculateArea() { return 3.14f * _radius * _radius; } private: float _radius; }; int main() { Shape *s1 = new Square(5); Shape *s2 = new Circle(3); std::cout << "Area of square is " << s1->calculateArea() << std::endl; std::cout << "Area of circle is " << s2->calculateArea() << std::endl; delete s1; delete s2; return 0; }
上面的代碼中,我們定義了一個基類`Shape`和兩個派生類`Square`和`Circle`,它們都實現了函數`calculateArea`。在調用函數`calculateArea`時,我們將基類指針指向派生類對象,可以看到運行時實際調用的是派生類的實現函數。
2、抽象類
抽象類是指包含至少一個純虛函數的類,這個類不能被實例化,只能用作基類來派生出其他類。在C++中,可以通過將函數聲明為純虛函數來實現抽象類。
下面是一個抽象類的示例代碼:
#include <iostream> class Shape { public: virtual float calculateArea() = 0; }; class Square : public Shape { public: Square(float l) : _length(l) {} virtual float calculateArea() { return _length * _length; } private: float _length; }; class Circle : public Shape { public: Circle(float r) : _radius(r) {} virtual float calculateArea() { return 3.14f * _radius * _radius; } private: float _radius; }; int main() { // Shape *s = new Shape(); // error: cannot instantiate abstract class Shape *s1 = new Square(5); Shape *s2 = new Circle(3); std::cout << "Area of square is " << s1->calculateArea() << std::endl; std::cout << "Area of circle is " << s2->calculateArea() << std::endl; delete s1; delete s2; return 0; }
上面的代碼中,我們將基類`Shape`中的函數`calculateArea`聲明為純虛函數,從而實現了抽象類。抽象類不能被實例化,只能用作基類來派生出其他類。在調用函數`calculateArea`時,我們將基類指針指向派生類對象,可以看到運行時實際調用的是派生類的實現函數。
四、總結
本文介紹了C++中實現運行時多態的兩種方式:靜態多態和動態多態。靜態多態包括函數重載和模板函數,動態多態包括虛函數和抽象類。通過對這些知識點的學習,可以更好地理解C++中的多態性,更靈活地應用在實際的程序開發中。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/159556.html