欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中實現(xiàn)多態(tài)有幾種方式小結

 更新時間:2024年12月05日 11:00:15   作者:黑果果的思考  
在C++中,多態(tài)是一種面向對象編程的特性,允許以統(tǒng)一的方式處理不同類型的對象,并根據(jù)實際對象的類型來執(zhí)行相應的操作,本文給大家介紹了C++中實現(xiàn)多態(tài)有幾種方式小結,需要的朋友可以參考下

多態(tài)的概念

多態(tài) 指的是 具有繼承關系 的不同對象在調(diào)用同一函數(shù) 時形成的不同狀態(tài)!

舉個例子:比如我們平時買高鐵/火車票時,不同的人買票買的結果都是不一樣的!學生是半價、成人是全價、軍人是軍人優(yōu)先票 等!而這三種對象本質都是繼承自同一個 Person 的父類,所以他們執(zhí)行同一操作時不同的結果就是多態(tài)!

• 構成多態(tài)的兩個必要條件

1、必須通過基類/父類的 指針或者引用 調(diào)用虛函數(shù)

2、派生類必須得對基類的虛函數(shù)進行重寫

舉個栗子先見一見:

class Person
{
public:
	// 虛函數(shù)
	virtual void BuyTicket()
	{
		cout << "Person::買票-成人-全價" << endl;
	}
};
 
class Student : public Person // 構成繼承關系
{
public:
	// 虛函數(shù)
	virtual void BuyTicket()
	{
		cout << "Student::買票-學生-半價" << endl;
	}
};
 
int main()
{
	// 父類對象的指針 調(diào)用虛函數(shù)
	Person* pp = new Student;
	pp->BuyTicket();
	// 父類對象的引用 調(diào)用子類的對象
	Student st;
	Person& rp = st;
	rp.BuyTicket();
 
	Person p;
	Person& r = p;// 父類對象的引用 調(diào)用虛函數(shù)
	r.BuyTicket();
	Person* ptr = &p;// 父類對象的指針 調(diào)用虛函數(shù)
	ptr->BuyTicket();
 
	return 0;
}

此時,不同的對象去以父類的指針/引用去調(diào)用虛函數(shù)時結果是不一樣的

下面由小編給大家總結一下C++實現(xiàn)多態(tài)的幾種方式!

一)虛函數(shù)(Virtual Functions)實現(xiàn)多態(tài)

概念:

虛函數(shù)是在基類中使用關鍵字virtual聲明的成員函數(shù)。當一個類包含虛函數(shù)時,編譯器會為該類創(chuàng)建一個虛函數(shù)表(v - table),這個表存儲了虛函數(shù)的地址。當通過基類指針或引用調(diào)用虛函數(shù)時,程序會根據(jù)對象的實際類型(即指針或引用所指向或引用的實際子類對象)來查找虛函數(shù)表,從而調(diào)用子類中重寫后的虛函數(shù),實現(xiàn)多態(tài)行為。

代碼示例:

class Shape 
{
public:
    virtual void draw() = 0; 
};
class Circle : public Shape 
{
public:
    void draw() override 
    {
        std::cout << "Drawing a circle." << std::endl;
    }
};
class Rectangle : public Shape 
{
public:
    void draw() override 
    {
        std::cout << "Drawing a rectangle." << std::endl;
    }
};

在這個例子中,Shape是一個抽象基類,draw是一個純虛函數(shù)。Circle和Rectangle是Shape的子類,它們重寫了draw函數(shù)。當使用
Shape* shapePtr;
shapePtr = new Circle();
shapePtr->draw();
或者
Shape circleObj;
Shape& shapeRef = circleObj;
shapeRef.draw();
(circleObj是Circle類的對象)這樣的方式調(diào)用draw函數(shù)時,會根據(jù)對象是Circle還是Rectangle來動態(tài)地調(diào)用相應子類的draw函數(shù),實現(xiàn)多態(tài)。

二)函數(shù)指針實現(xiàn)多態(tài)(較少使用,但在某些特定場景下有效)

概念:

可以通過定義函數(shù)指針,讓函數(shù)指針指向不同的函數(shù)實現(xiàn)來達到類似多態(tài)的效果。函數(shù)指針可以根據(jù)具體的情況(如運行時的條件)來改變它所指向的函數(shù),從而實現(xiàn)不同的行為。不過這種方式與虛函數(shù)相比,沒有自動的動態(tài)綁定機制,需要手動管理函數(shù)指針的指向。

代碼示例:

// 定義函數(shù)指針類型,該函數(shù)接受無參數(shù),返回void
typedef void (*DrawFunction)();
class Shape 
{
public:
    DrawFunction drawFunction;
    Shape(DrawFunction df) : drawFunction(df) {}
    void draw() 
    {
        drawFunction();
    }
};
void drawCircle() 
{
    std::cout << "Drawing a circle using function pointer." << std::endl;
}
void drawRectangle() 
{
    std::cout << "Drawing a rectangle using function pointer." << std::endl;
}
int main() 
{
    Shape circleShape(drawCircle);
    Shape rectangleShape(drawRectangle);
    circleShape.draw();
    rectangleShape.draw();
    return 0;
}

在這個例子中,Shape類中有一個DrawFunction類型的函數(shù)指針drawFunction。在構造函數(shù)中,可以傳入不同的函數(shù)來初始化這個函數(shù)指針。當調(diào)用draw方法時,就會執(zhí)行函數(shù)指針所指向的函數(shù)。通過這種方式,可以實現(xiàn)根據(jù)不同的對象(這里通過不同的構造方式)來執(zhí)行不同的繪制函數(shù),達到類似多態(tài)的效果。不過這種方式需要手動設置函數(shù)指針,而且對于繼承體系的支持不如虛函數(shù)方便。
代碼示例:

#include <iostream>
// 定義函數(shù)指針類型,該函數(shù)接受兩個整數(shù)參數(shù)并返回一個整數(shù)
typedef int (*MathOperation)(int, int);
int add(int a, int b) 
{
    return a + b;
}
int subtract(int a, int b) 
{
    return a - b;
}
int main()
{
    MathOperation operation;
    operation = add;
    int result1 = operation(5, 3);
    operation = subtract;
    int result2 = operation(5, 3);
    std::cout << "加法結果: " << result1 << std::endl;
    std::cout << "減法結果: " << result2 << std::endl;
    return 0;
}

在這個例子中,MathOperation是一個函數(shù)指針類型。通過將operation函數(shù)指針先后指向add函數(shù)和subtract函數(shù),實現(xiàn)了根據(jù)需要調(diào)用不同函數(shù)的效果,從而在一定程度上實現(xiàn)了多態(tài)。

三)模板(Templates)實現(xiàn)編譯時多態(tài)(也稱為參數(shù)化多態(tài))

概念:

模板是 C++ 中的泛型編程機制。雖然它不是真正的多態(tài)(因為它是在編譯時確定具體的函數(shù)或類的版本,而不是運行時),但在某些情況下可以實現(xiàn)類似多態(tài)的代碼復用和靈活性。通過模板,可以編寫通用的代碼,這些代碼可以根據(jù)不同的類型參數(shù)生成不同的具體實現(xiàn),從而適應多種數(shù)據(jù)類型或類類型的需求。

代碼示例(函數(shù)模板):

template<typename T>
void draw(T& shape) 
{
    shape.draw();
}
class Circle 
{
public:
    void draw() 
    {
        std::cout << "Drawing a circle using template." << std::endl;
    }
};
class Rectangle 
{
public:
    void draw() 
    {
        std::cout << "Drawing a rectangle using template." << std::endl;
    }
};
int main() 
{
    Circle circle;
    Rectangle rectangle;
    draw(circle);
    draw(rectangle);
    return 0;
}

在這個例子中,draw是一個函數(shù)模板,它可以接受不同類型的參數(shù)(只要這個類型有draw方法)。當傳入Circle或Rectangle對象時,會在編譯時根據(jù)對象的類型生成對應的draw函數(shù)調(diào)用,實現(xiàn)了對不同類型對象的通用處理,有點類似于多態(tài)的效果,但這種方式是基于編譯時的類型推導,而不是像虛函數(shù)那樣的運行時多態(tài)。

四)抽象基類與純虛函數(shù)結合實現(xiàn)多態(tài)(與虛函數(shù)方式緊密相關)

概念:

抽象基類是包含純虛函數(shù)的類,不能被實例化。純虛函數(shù)是在基類中聲明但沒有定義的虛函數(shù),它強制子類必須重寫這個函數(shù)。通過這種方式,可以定義一個通用的接口,子類必須實現(xiàn)這個接口,從而實現(xiàn)多態(tài)。當通過基類指針或引用調(diào)用這些純虛函數(shù)時,會根據(jù)子類的實際實現(xiàn)來調(diào)用相應的函數(shù)。

代碼示例(與前面虛函數(shù)示例結合):

class Shape
{
public:
virtual void draw() = 0;
};

這里Shape是抽象基類,draw是純虛函數(shù)。子類必須重寫draw函數(shù)才能實例化,這樣就確保了在通過Shape基類指針或引用調(diào)用draw函數(shù)時,能夠根據(jù)具體子類的實現(xiàn)來獲得不同的繪制行為,實現(xiàn)多態(tài)。這種方式明確了接口規(guī)范,并且和虛函數(shù)的動態(tài)綁定機制一起,是 C++ 實現(xiàn)多態(tài)的重要方式之一。

五)函數(shù)重載(Function Overloading)實現(xiàn)有限的多態(tài)性

概念:

函數(shù)重載是指在同一個作用域內(nèi),可以有多個同名函數(shù),它們的參數(shù)列表(參數(shù)個數(shù)、類型、順序)不同。當調(diào)用一個重載函數(shù)時,編譯器會根據(jù)傳入的實際參數(shù)來確定調(diào)用哪一個具體的函數(shù)版本。這種方式在一定程度上實現(xiàn)了多態(tài)性,因為相同的函數(shù)名可以根據(jù)不同的參數(shù)類型執(zhí)行不同的操作。

代碼示例:

#include <iostream>
class Calculator 
{
public:
    int add(int a, int b)
    {
        return a + b;
    }
    double add(double a, double b) 
    {
        return a + b;
    }
};
int main() 
{
    Calculator calculator;
    int intResult = calculator.add(3, 5);
    double doubleResult = calculator.add(3.5, 2.5);
    std::cout << "整數(shù)相加結果: " << intResult << std::endl;
    std::cout << "浮點數(shù)相加結果: " << doubleResult << std::endl;
    return 0;
}

在這個例子中,Calculator類中有兩個add函數(shù),一個用于整數(shù)相加,一個用于浮點數(shù)相加。編譯器會根據(jù)傳入add函數(shù)的參數(shù)類型來決定調(diào)用哪個版本,這就像一種簡單的多態(tài),根據(jù)參數(shù)類型的不同選擇不同的操作方式。不過,函數(shù)重載是在編譯時確定調(diào)用的函數(shù)版本,而不是像虛函數(shù)那樣在運行時動態(tài)綁定。

六)函數(shù)對象(仿函數(shù),F(xiàn)unctors):

原理:函數(shù)對象是一個類,它重載了函數(shù)調(diào)用運算符operator()。這樣,這個類的對象就可以像函數(shù)一樣被調(diào)用。例如:

class AddFunctor 
{
public:
    int operator()(int a, int b) const 
    {
        return a + b;
    }
};
class SubtractFunctor 
{
public:
    int operator()(int a, int b) const 
    {
        return a - b;
    }
};
int main() 
{
    AddFunctor addObj;
    SubtractFunctor subtractObj;
    int result1 = addObj(3, 2);
    int result2 = subtractObj(3, 2);
    return 0;
}

應用場景:在 STL 算法中廣泛使用。例如,std::sort函數(shù)可以接受一個比較函數(shù)對象來確定排序的順序。不同的比較函數(shù)對象可以實現(xiàn)不同的排序規(guī)則(如升序、降序),通過這種方式實現(xiàn)了基于不同規(guī)則的排序多態(tài)性。同時,函數(shù)對象可以攜帶狀態(tài)(通過類的成員變量),這是函數(shù)指針所不具備的優(yōu)勢,在一些需要記錄中間狀態(tài)的場景中非常有用。

以上就是C++中實現(xiàn)多態(tài)有幾種方式小結的詳細內(nèi)容,更多關于C++實現(xiàn)多態(tài)方式的資料請關注腳本之家其它相關文章!

相關文章

  • C++中Boost的智能指針weak_ptr

    C++中Boost的智能指針weak_ptr

    這篇文章介紹了C++中Boost的智能指針weak_ptr,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • C語言實現(xiàn)動態(tài)擴容的string

    C語言實現(xiàn)動態(tài)擴容的string

    最近工作中使用C語言,但又苦于沒有高效的字符串實現(xiàn),字符串的拼接和裁剪都很麻煩,而且每個字符串都需要申請內(nèi)存,內(nèi)存的申請和釋放也很容易出bug,怎么高效的實現(xiàn)一個不需要處理內(nèi)存問題并且可以動態(tài)擴容進行拼接和裁剪的string呢?本文就來詳細講講
    2023-04-04
  • 深入理解memmove()與memcpy()的區(qū)別以及實現(xiàn)方法

    深入理解memmove()與memcpy()的區(qū)別以及實現(xiàn)方法

    本篇文章是對memmove()與memcpy()的區(qū)別以及實現(xiàn)方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++實現(xiàn)雙向鏈表

    C++實現(xiàn)雙向鏈表

    這篇文章主要為大家詳細介紹了C++實現(xiàn)雙向鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • strtok函數(shù)的使用示例

    strtok函數(shù)的使用示例

    今天小編就為大家分享一篇關于strtok函數(shù)的使用示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • VS2022中使用Copilot的圖文教程

    VS2022中使用Copilot的圖文教程

    大家都知道Copilot可以自動幫助寫代碼,那么這個工具是如果使用的呢?很多朋友不是很清楚,今天小編給大家分享一篇教程關于VS2022中使用Copilot的圖文教程,感興趣的朋友一起看看吧
    2022-04-04
  • C語言編程之預處理過程與define及條件編譯

    C語言編程之預處理過程與define及條件編譯

    這篇文章主要為大家介紹了C語言編程之預處理過程與define及條件編譯,文中通過圖文及示例代碼方式作了詳細的解釋,有需要的朋友可以借鑒參考下
    2021-09-09
  • 深度解析C語言中數(shù)據(jù)的存儲

    深度解析C語言中數(shù)據(jù)的存儲

    本文詳細介紹了C語言中數(shù)據(jù)的存儲,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • 深入理解Qt中各種消息框對話框的使用

    深入理解Qt中各種消息框對話框的使用

    本篇文章主要介紹了Qt中各種消息框的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • C語言實現(xiàn)銷售管理系統(tǒng)

    C語言實現(xiàn)銷售管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)銷售管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02

最新評論