C++——多態、抽象類和接口

目錄

多態的基本概念

如何實現多態

在C++中,派生類對象可以被當作基類對象使用

編程示例

關鍵概念總結

抽象類

一、抽象類的定義

基本語法

二、抽象類的核心特性

1. 不能直接實例化

2.?派生類必須實現所有純虛函數才能成為具體類

3.?可以包含普通成員函數和數據成員

編程示例

關鍵點說明

接口

接口的基本概念


多態的基本概念

想象一下,你有一個遙控器(這就像是一個基類的指針),這個遙控器可以控制不同的電子設備(這些設備就像是派生類。無論是電視、音響還是燈光,遙控器上的“開/按鈕(這個按鈕就像是一個虛函數)都能控制它們,但具體的操作(打開電視、播放音樂、開燈)則取決于你指向的設備。

如何實現多態

1. 使用虛函數(Virtual Function

我們在基類中定義一個虛函數,這個函數可以在任何派生類中被重寫或者說定制。使用關鍵字 virtual 來聲明。

2. 創建派生類并重寫虛函數

在派生類中,我們提供該虛函數的具體實現。這就像是告訴遙控器,當你控制我的這個設備時,這個按鈕應該這樣工作”

3. 通過基類的引用或指針調用虛函數

當我們使用基類類型的指針或引用來調用虛函數時,實際調用的是對象的實際類型(派生類)中的函數版本。

當基類包含至少一個虛函數(通常是純虛函數),派生類重寫該函數后,在main函數中用基類指針指向派生類對象,并通過該指針調用虛函數時,實際調用的是派生類的實現,這種現象稱為多態。

在C++中,派生類對象可以被當作基類對象使用

  • 派生類對象可以直接賦值給基類指針/引用

  • 但反過來不行(基類對象不能當作派生類對象)

編程示例

#include <iostream>
using namespace std;// 基類——遙控器(抽象概念)
class RemoteCon
{
public:// 虛函數:聲明遙控器的"開啟"功能,允許子類重寫virtual void open() = 0; // 純虛函數(=0表示沒有默認實現)// 這樣RemoteCon就成為抽象類,不能直接實例化
};// 派生類——電視遙控器,繼承于基類遙控器
class TVRemoteCon : public RemoteCon
{
public:// 重寫(override)基類的open函數void open() override{cout << "電視遙控器開啟鍵被按下" << endl;}
};// 派生類——燈光遙控器,繼承于基類遙控器
class LightRemoteCon : public RemoteCon
{
public:void open() override{cout << "燈光遙控器開啟鍵被按下" << endl;}
};// 派生類——空調遙控器,繼承于基類遙控器
class AirConditionerRemoteCon : public RemoteCon
{
public:void open() override{cout << "空調遙控器開啟鍵被按下" << endl;}
};int main()
{// 第一部分:通過指針實現多態// 創建一個指向電視遙控器的基類指針RemoteCon* remoteCon = new TVRemoteCon();  remoteCon->open();  // 調用TVRemoteCon的open()// 創建一個指向燈光遙控器的基類指針RemoteCon* remoteCon2 = new LightRemoteCon();remoteCon2->open();  // 調用LightRemoteCon的open()// 第二部分:通過引用實現多態AirConditionerRemoteCon kongTiao;  // 創建空調遙控器對象RemoteCon& remoteCon3 = kongTiao;  // 創建基類引用綁定到派生類對象remoteCon3.open();  // 調用AirConditionerRemoteCon的open()// 釋放動態分配的內存delete remoteCon;delete remoteCon2;return 0;
}

代碼解釋:

RemoteCon *remoteCon = new TVRemoteCon; // 創建一個指向電視的遙控器指針
remoteCon->open();

盡管?remoteCon?是?RemoteCon*?類型的指針,但它實際指向的是?TVRemoteCon?對象。在運行時,C++ 的多態機制會依據對象的實際類型來調用相應的?open?函數實現,所以這里調用的是?TVRemoteCon?類中的?open?函數。

關鍵概念總結

  1. 虛函數(virtual):允許函數在派生類中被重寫

  2. override關鍵字:明確表示重寫基類虛函數

  3. 多態兩種實現

    • 基類指針指向派生類對象

    • 基類引用綁定派生類對象

  4. 運行時綁定:具體調用哪個函數在運行時決定

抽象類

一、抽象類的定義

抽象類是指包含至少一個純虛函數的類,它不能被實例化,只能作為其他類的基類。

基本語法

class 抽象類名 {
public:virtual 返回類型 函數名(參數列表) = 0; // 純虛函數// 其他成員...
};

二、抽象類的核心特性

1. 不能直接實例化

class Shape {
public:virtual double area() = 0;
};// Shape s;  // 錯誤!不能創建抽象類對象

2.?派生類必須實現所有純虛函數才能成為具體類

class Circle : public Shape {
public:double area() override { return 3.14*r*r; } // 必須實現
};

3.?可以包含普通成員函數和數據成員

class Animal {
public:virtual void speak() = 0;void eat() { cout << "Eating..." << endl; } // 普通成員函數
protected:int age; // 數據成員
};

編程示例

#include <iostream>using namespace std;// 這是一個抽象類,包含3個純虛函數
// 因為有純虛函數,所有這個類不能被實例化
class Teacher { 
public:virtual void course() = 0;    // 聲明課程內容的純虛函數virtual void startClass() = 0; // 開始上課的純虛函數virtual void endClass() = 0;   // 結束課程的純虛函數
};// 具體派生類 EnglishTeacher
class EnglishTeacher : public Teacher {
public:void course() override {cout << "這節課是英語課" << endl;}void startClass() override {cout << "開始上英語課" << endl;}void endClass() override {cout << "英語課結束" << endl;}
};// 具體派生類 ProTeacher
class ProTeacher : public Teacher {
public:void course() override {cout << "這節課是C++" << endl;}void startClass() override {cout << "開始上C++" << endl;}void endClass() override {cout << "C++結束" << endl;}
};int main() {// 直接使用具體類EnglishTeacher t;t.course();      // 輸出: 這節課是英語課t.startClass();  // 輸出: 開始上英語課t.endClass();    // 輸出: 英語課結束// 多態用法Teacher* t2 = new ProTeacher;t2->course();     // 輸出: 這節課是C++t2->startClass(); // 輸出: 開始上C++t2->endClass();   // 輸出: C++結束delete t2; // 記得釋放內存return 0;
}

關鍵點說明

  1. 多態的實現

    • 通過基類指針Teacher*指向派生類對象ProTeacher

    • 調用虛函數時,實際執行的是派生類的實現

  2. override關鍵字

    • 確保函數確實重寫了基類的虛函數

    • 如果簽名不匹配,編譯器會報錯

  3. 抽象類的作用

    • 強制派生類實現特定接口

    • 統一了不同種類教師的調用方式

  4. 內存管理

    • 示例中new ProTeacher需要手動delete

接口

在C++中,接口是一種特殊的抽象類,它只包含純虛函數而不包含任何數據成員或具體實現。接口用于定義行為規范,讓不同的類可以遵循相同的接口標準。

接口的基本概念

C++ 中,雖然沒有像其他編程語言(比如 Java 中的接口Interface)一樣直接定義接口的關鍵字,但可以通過抽象類和純虛函數的方式來實現接口的概念。

接口通常用于定義類應該實現的方法,但不提供具體實現。這樣的實現方式允許多個類共享相同的接口,同時讓每個類根據需要去實現這些接口。

一個類作為接口可以通過以下步驟來實現:

1. 定義抽象類:創建一個包含純虛函數的抽象類,這些函數構成了接口的一部分。這些函數在抽象類中只有聲明而沒有具體的實現。

2. 派生類實現接口:派生類繼承抽象類,并實現其中的純虛函數,以具體實現接口定義的方法。

#include <iostream>using namespace std;class Person // 接口
{
public:virtual void eat() = 0; // 吃virtual void drink() = 0; // 喝virtual void haveFun() = 0; // 玩樂
};class Woman : public Person
{
public:void eat() override{cout << "麻辣雞腿堡" << endl;}void drink() override{cout << "珍珠奶茶" << endl;}void haveFun() override{cout << "劇本殺" << endl;}
};class Man : public Person
{
public:void eat() override{cout << "板燒雞腿堡" << endl;}void drink() override{cout << "可樂" << endl;}void haveFun() override{cout << "打桌球" << endl;}
};int main()
{Woman w;w.eat();w.drink();w.haveFun();Man m;m.eat();m.drink();m.haveFun();return 0;
}

Person?類是一個抽象基類,它包含了三個純虛函數(eat(),?drink(),?haveFun()),這實際上起到了接口的作用。

Woman?和?Man?類繼承自?Person?并實現了所有這些純虛函數。

所以可以說這是一個接口的實現,但更準確的說法是:

  • 這是一個使用 C++ 純虛函數實現的接口設計模式

  • Person?類扮演了接口的角色

  • Woman?和?Man?是具體實現這個接口的類

在 C++ 中,這種設計常被稱為"接口類"或"抽象基類",它強制派生類必須實現這些方法,這正是接口的核心特性。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902427.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902427.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902427.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初級達夢dba的技能水準

在x86環境&#xff08;windows、linux&#xff09;安裝單機軟件&#xff0c;安裝客戶端創建過至少20套數據庫&#xff0c;優化參數并更新過正式許可會用邏輯導出導入以及dmrman備份了解manager工具的使用配置sqllog日志&#xff0c;并能解釋輸出內容能夠分析因磁盤空間不足、內…

監控頁面卡頓PerformanceObserver

監控頁面卡頓PerformanceObserver 性能觀察器掘金 const observer new PerformanceObserver((list) > {}); observer.observe({entryTypes: [longtask], })

智能座艙測試內容與步驟

智能座艙的測試步驟通常包括以下環節&#xff1a; 1.測試環境搭建與準備 ? 硬件需求分析&#xff1a;準備測試車輛、服務器與工作站、網絡設備以及傳感器和執行器模擬器等硬件設備。 ? 軟件需求分析&#xff1a;選擇測試管理軟件、自動化測試工具、模擬軟件和開發調試工具等。…

Redis——網絡模型

目錄 前言 1.用戶空間和內核空間 1.2用戶空間和內核空間的切換 1.3切換過程 2.阻塞IO 3.非阻塞IO 4.IO多路復用 4.1.IO多路復用過程 4.2.IO多路復用監聽方式 4.3.IO多路復用-select 4.4.IO多路復用-poll 4.5.IO多路復用-epoll 4.6.select poll epoll總結 4.7.IO多…

電力系統中為什么采用三相交流電?

電力系統中為什么采用三相交流電 電力系統中采用三相交流電&#xff0c;主要是因為它在輸電效率、設備使用、能量傳輸平穩性等方面相比單相交流或直流電具有顯著優勢。下面我詳細解釋一下原因&#xff1a; &#x1f31f; 1. 提高輸電效率&#xff08;節省電纜材料&#xff09;…

python簡介與入門

目錄 python初始 python的優勢 python的特性 python的應用領域 Linux環境中安裝python 下載python3.11.6 安裝依賴包 解壓python壓縮包 安裝python 編譯及安裝 建立軟連接 測試python3運行 設置國內pip更新源 更新pip版本&#xff08;必須更新&#xff09; wind…

Web內網滲透知識大全

內網滲透 端口轉發 需要三個主機&#xff0c;Windows7、Windows2016、kali Windows7為內網主機 Windows2016為跳板機 kali為攻擊機 使用到的工具 netsh、MSF 我們先在Windows7上開啟一個80服務&#xff0c;而這個80服務只能由Windows2016訪問&#xff0c;kali不能訪問 我們…

ffmpeg av_buffer_unref的邏輯實現; av_freep 和 av_freep函數的區別

av_buffer_unref 是 FFmpeg 中用于管理引用計數和內存釋放的核心函數&#xff0c;其內部實現機制如下&#xff1a; ?一、核心流程? ?引用計數遞減? 函數首先對 AVBufferRef 的 buffer->refcount 進行原子遞減操作&#xff08;通過 atomic_fetch_add_explicit 等機制保證…

從 GPS 數據中捕捉城市休閑熱點:空間異質性視角下的新框架

從 GPS 數據中捕捉城市休閑熱點&#xff1a;空間異質性視角下的新框架 原文&#xff1a;Capturing urban recreational hotspots from GPS data: A new framework in the lens of spatial heterogeneity 1. 背景與意義 城市娛樂活動的重要性&#xff1a; 娛樂活動是城市生活…

rk3568main.cc解析

rk3568main.cc解析 前言解析前言 正點原子rk3568學習,rk官方RKNN_MODEL_ZOO文件中 rknn_model_zoo-main/examples/mobilenet/cpp/main.cc 從執行命令:./build-linux.sh -t rk3568 -a aarch64 -d mobilenet 到: cmake ../../examples/mobilenet/cpp \-DTARGET_SOC=rk356x\…

【實驗數據處理matlab程序】程序1:繪制figure文件中曲線的RMS值

立意 在本課題所涉及的實驗中&#xff0c;需要將2個拉線式位移傳感器中的數據收集并處理&#xff0c;在此基礎上求解相應的速度 主要功能 針對一個figure文件中僅包含一個plot&#xff0c;且該plot中包含指定數目的曲線&#xff0c;求這些曲線的RMS值&#xff1b;針對一個fi…

kotlin的kmp編程中遇到Unresolved reference ‘java‘問題

解決辦法 打開 File → Project Structure → Project 確保 Project SDK 是 與你的 jvmToolchain 保持一致 如果沒有&#xff0c;點擊右上角 Add SDK 添加 JDK 路徑 同步Sync 然后就正常了。 package org.example.projectimport androidx.compose.animation.AnimatedVi…

靜電放電測試中垂直和水平耦合板的作用

在靜電放電&#xff08;ESD&#xff0c;Electrostatic Discharge&#xff09;測試中&#xff0c;垂直耦合板&#xff08;Vertical Coupling Plane, VCP&#xff09;和水平耦合板&#xff08;Horizontal Coupling Plane, HCP&#xff09;是模擬設備在實際環境中因靜電放電產生的…

Web開發-JavaEE應用JNDI注入RMI服務LDAP服務DNS服務高版本限制繞過

知識點&#xff1a; 1、安全開發-JavaEE-JNDI注入-LADP&RMI&DNS等 2、安全開發-JavaEE-JNDI注入-項目工具&手工原理等 演示案例-WEB開發-JavaEE-JNDI注入&LDAP&RMI服務&DNS服務&高版本限制繞過 JNDI全稱為 Java Naming and DirectoryInterface&am…

基于Transformer與隨機森林的多變量時間序列預測

哈嘍&#xff0c;我不是小upper&#xff0c;今天和大家聊聊基于Transformer與隨機森林的多變量時間序列預測。 不懂Transformer的小伙伴可以看我上篇文章:一文帶你徹底搞懂&#xff01;Transformer &#xff01;&#xff01;https://blog.csdn.net/qq_70350287/article/detail…

初識網絡原理

文章目錄 1.IP地址2.端口號3.網絡中的五元組4.協議分層5.封裝和分用6.客戶端與服務器 1.IP地址 IP地址 (IP Address): 用于在網絡中唯一標識一臺設備&#xff08;主機、路由器等&#xff09;。IP地址分為IPv4和IPv6兩種版本。IPv4是32位地址&#xff0c;通常表示為四個用點分隔…

健康養生之道

健康養生是一種積極的生活態度&#xff0c;是對自己和家人的關愛。從生活的細微之處做起&#xff0c;便能為健康打下堅實的基礎。 在生活習慣方面&#xff0c;要注重細節。保持居住環境的整潔與通風&#xff0c;讓生活空間舒適宜人。勤洗手、勤換洗衣物&#xff0c;養成良好的衛…

幾種電氣絕緣類型

1. 基本絕緣 1.1 絕緣等級 1.2 I類設備 2. 附加絕緣 3. 雙重絕緣 4. 加強絕緣 5. 功能性絕緣 1. 基本絕緣 用于防止觸及帶電部件的初級保護,該防護是由絕緣材料完成的 基本絕緣的目的在于為防電擊提供一個基本的保護,以避免觸電的危險,不過此類絕緣只能保證正常狀態下…

01.瀏覽器自動化webdriver源碼分析之啟動函數

日后&#xff0c;網絡爬蟲也好&#xff0c;數據采集也好&#xff0c;自動化必然是主流。因此&#xff0c;筆者未雨綢繆&#xff0c;在此研究各類自動化源碼&#xff0c;希望能夠趕上時代&#xff0c;做出一套實用的自動化框架。 這里先研究傳統的webdriver中轉來進行瀏覽器自動…

PLOG安裝

Plog可以通過以下命令安裝 cd ~ && git clone https://github.com/SergiusTheBest/plog.gitcd plog && mkdir buildcd build && cmake ..make && sudo make installcd ~ && sudo rm -rf ./plog若無法科學上網&#xff0c;可使用git cl…