C++中的抽象基類(Abstract Base Class)
背景:
有時候,我們想呼叫兩個相似類的同名函式,如下圖:
Circle類:
class Circle
{
public:
Circle(double radius)
: radius{radius}
{
}
double area() const
{
return radius * radius * 3.1415927;
}
private:
double radius;
};
Rectangle類:
class Rectangle
{
public:
Rectangle(double width, double height)
: width{width}, height{height}
{
}
double area() const
{
return width * height;
}
private:
double width;
double height;
};
現在,在我們的主函式中,我們想把兩個類傳到函式的引數中,問題來了,我們如何確定這個引數是什麼型別?
void printArea(??? someShape)
{
std::cout << "The area of the shape is " << someShape.area() << std::endl;
}
我們可以用笨方法,寫兩個函式,一個使用Circle型別,一個使用Rectangle型別,就可以解決這個問題。但會不會太麻煩了?如果我們有更多的類呢?
這時候,就要用到這篇部落格的主題了:抽象基類。
抽象基類
我們可以使用一個父類,讓Circle和Rectangle類變成它的子類,從而可以override相同的函式。而在printArea函式中,我們只要傳入這個父類就可以了。
我們可以在父類裡寫一個隨便返回任何值的area函式,然後在每個子類中具體實現area的功能。
class Shape
{
public:
virtual double area() const
{
return -1.0;
}
}
現在,我們可以在Circle和Rectangle檔案中繼承Shape類,加入override關鍵字,從而在printArea函式中就可以傳入Shape型別了。
void printArea(const Shape& someShape)
{
std::cout << "The area of the shape is " << someShape.area() << std::endl;
}
問題:
現在,我們已經可以得到我們想要的了,不過有一點小問題:
void foo(Circle c)
{
}
foo(5.0);
如果我們執行這段程式碼,計算機不會報錯,相反,它會把5.0當成半徑。這種情況只會出現在類只有一個引數的時候。這種情況在C++中叫做 隱式型別轉換 (implicit type conversion)。
我們可以用關鍵字explicit解決這個問題
class Circle
{
public:
explicit Circle(double radius)
: radius{radius}
{
}
double area() const
{
return radius * radius * 3.1415927;
}
private:
double radius;
};
還有一個小問題是關於父類的。返回一個隨意值不是一個很簡潔的方法,因為我們完全不需要這個函式去實現任何東西。
class Shape
{
public:
virtual double area() const = 0;
}
這裡讓最後 = 0,使這個函式變成了純虛擬函式,僅用於抽象基類的子類去重新定義此函式。
========================================
以上是C++抽象基類的簡單介紹
//此部落格用於自我學習的記錄,若某處不當請指正:)
相關文章
- PHP中的 抽象類(abstract class)和 介面(interface)PHP抽象
- TypeScript abstract 抽象類TypeScript抽象
- java中的抽象類abstract怎麼使用?Java抽象
- 介面和抽象類 (abstract)抽象
- Typescript的interface、class和abstract classTypeScript
- JavaSE第三章 物件導向 抽象類 abstractJava物件抽象
- C++ 抽象類快速使用C++抽象
- Java —— 流的抽象基類Java抽象
- 抽象語法樹 Abstract syntax tree抽象語法樹
- 走進C# abstract,瞭解抽象類與介面的異同C#抽象
- Python抽象基類abcPython抽象
- java中的抽象類與介面Java抽象
- Abstract Factory(抽象工廠)——物件建立型模式抽象物件模式
- PHP 抽象類繼承抽象類時的注意點PHP 抽象類繼承抽象類時的注意點PHP抽象繼承
- Java基礎-抽象類和介面Java抽象
- 介面是否可繼承(extends)介面? 抽象類是否可實現 (implements)介面? 抽象類是否可繼承具體類(concrete class)?繼承抽象
- 設計模式-抽象工廠模式(Abstract Factory Pattern)設計模式抽象
- 設計模式--抽象工廠模式(Abstract Factory Pattern)設計模式抽象
- C++基礎(八)struct和class的區別C++Struct
- java中抽象類和介面Java抽象
- Java中的介面與抽象類詳解Java抽象
- PHP中的抽象類、介面與性狀PHP抽象
- 抽象方法和抽象類抽象
- 抽象類抽象
- 介面的行為抽象和抽象類的行為抽象抽象
- C++中的容器類C++
- JAVA基礎之三-介面和抽象類Java抽象
- 抽象基類和純虛擬函式抽象函式
- 設計模式實戰 - 抽象工廠模式(Abstract Factory Pattern)設計模式抽象
- 設計模式實戰 – 抽象工廠模式(Abstract Factory Pattern)設計模式抽象
- Java的抽象類 & 介面Java抽象
- C++快速入門--12--抽象類和介面模擬C++抽象
- Java 抽象類Java抽象
- 14、抽象類抽象
- Python抽象類Python抽象
- 關於在Interface和Abstract Class間選擇的一些思考
- 【圖解設計模式系列】The Abstract Factory Pattern: 抽象工廠模式圖解設計模式抽象
- Java中的介面與抽象類設計原則Java抽象