c++第八天-多態

  1. 虛函數
  2. 虛析構函數
  3. 純虛函數與抽象類

多態實現的條件:(1)公有繼承 (2)派生類重寫基類虛函數 (3)基類指針/引用指向派生類對象

虛函數不能是構造函數,不能是靜態函數,不能是友元函數,只能是普通的成員函數。

其中,綁定的含義是什么?

綁定分為兩類,一類是靜態綁定,一類是動態綁定

靜態綁定:在編譯階段,普通成員函數、全局函數、重載函數這些都是靜態綁定

動態綁定:在運行階段,程序才能確定函數調用對應的具體函數,只有virtual聲明的虛函數,并且用基類指針引用調用時,此案呢個發生動態綁定。

綁定就是確定函數調用到底會執行哪一個函數體的過程。

靜態綁定就是在編譯時綁定,動態綁定就是在運行時綁定。

綁定就是“函數調用和函數實現之間的對應關系是何時確定”的過程。

?基類聲明了虛函數,產生虛函數表,將虛函數放入。類多一個隱含的虛函數指針,指向虛函數表。派生類繼承時,會更新虛函數指針,指向自己的虛函數表,派生類重寫的虛函數會放入派生類的虛函數表中。基類指針/引用指向派生類對象的時候,通過指針/引用調用虛函數時,會先通過派生類對象的虛函數指針到虛函數表中查找,如果有就會調用派生類的虛函數。

通過對象名無法實現多態。

#include<iostream>
using namespace std;class A{
public:virtual void func() {cout << "A::func" << endl;}
};class B : public A{
public:void func() {cout << "B::func" << endl;}
};int main()
{A* pa = new B();pa->func();     //多態,基類用指針調用派生類的虛函數A a;B b;a = b;a.func();   //不是多態,對象名無法調用派生類的成員函數,C++語法規則return 0;
}

補充:override/final

因為基類中聲明了虛函數,這個函數在派生類中即使不加virtual,它在派生類中仍然是虛函數。所以在類的多層繼承的情況下,一個成員函數很難看出是不是虛函數,可以通過override確保這個函數在某個基類中聲明過虛函數,那么他就是虛函數。

class A{
public:    virtual void func() {cout << "A::func()" << endl;}void show() {cout << "A::show" << endl;}
};class B : public A{
public:void func() override {cout << "B::func" << endl;}void show() override {cout << "B::show" << endl;}
};

final: 修飾類時表示類不能被繼承;修飾虛函數時表示虛函數不能被重寫。

虛析構函數

?????????構造函數不能聲明為虛函數,原因是構造函數在對象創建完之前調用的,此時還沒有虛函數表和虛函數指針。

????????析構函數在對象釋放時調用,此時對象已經創建完成了,所以它有條件聲明為虛函數。而且,應該聲明成虛函數。

????????如果析構函數不是虛函數的話,基類指針指向派生類對象,通過基類指針釋放對象空間時,只會調用基類析構函數,而不會調用派生類析構函數,這樣會導致派生類中的動態內存單元不被釋放。

?

#include<iostream>
using namespace std;
class Base {			//基類Base
public:virtual ~Base();		//虛析構函數
};Base::~Base() {cout << "Base類析構函數" << endl;
}class Derive :public Base {		//派生類Derive公有繼承Base類
public:~Derive();		//虛析構函數
};Derive::~Derive()
{cout << "Derive類析構函數" << endl;
}int main() {Base* pb = new Derive;		//基類指針指向派生類對象delete pb;return 0;
}

純虛函數與抽象類

當基類非常抽象時,它的函數代碼不好實現,不能只寫出函數原型,而不寫代碼,定義這個函數的目的,是為了規范它的所有派生類都必須要有的函數,它的作用相當于接口。

純虛函數定義的語法:

virtual 函數返回值類型函數名(參數列表) = ?0

如果一個類中包含純虛函數,這樣的類稱為抽象類。

抽象類的作用就是為了定義接口,方便實現多態。

抽象類不能創建對象,只能作為基類派生。

抽象類中如果有多個純虛函數,派生類沒有全部實現,此時派生類仍然是抽象類。

?

#include<iostream>
using namespace std;class Animal{   //動物類Animal
public:virtual void speak() = 0;   //純虛函數virtual void eat() = 0;     //純虛函數virtual ~Animal();          //析構函數
};Animal :: ~Animal()
{cout << "調用Animal析構函數" << endl;
}class Cat : public Animal{
public:void speak();void eat();~Cat();
};void Cat :: speak() {cout << "小貓喵喵叫" << endl;}
void Cat :: eat() {cout << "小貓吃魚" << endl;}
Cat :: ~Cat() {cout << "調用Cat析構函數" << endl;}
class Rabbit :public Animal {	//兔子類Rabbit公有繼承Animal類
public:void speak();		//聲明speak()函數void eat();		//聲明eat()函數~Rabbit();		//聲明析構函數
};
void Rabbit::speak() { cout << "小兔子咕咕叫" << endl; }
void Rabbit::eat() { cout << "小兔子吃白菜" << endl; }
Rabbit::~Rabbit() { cout << "調用Rabbit析構函數" << endl; }int main() {Animal* pa = new Cat;	//定義基類指針pC指向Cat類對象pa->speak();		//通過pC指針調用speak()函數pa->eat();		//通過pC指針調用eat()函數delete pa;		//釋放指針pC指向的空間pa = new Rabbit;	//定義基類指針pR指向Rabbit類對象pa->speak();		//通過pR指針調用speak()函數pa->eat();		//通過pR指針調用eat()函數delete pa;		//釋放pR指向的空間return 0;
}

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

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

相關文章

全景圖渲染Vue3+TS使用Photo Sphere Viewer插件實現

1.Photo Sphere Viewer插件安裝: title=插件安裝 體驗AI代碼助手 代碼解讀復制代碼npm install photo-sphere-viewer -S 或 yarn add photo-sphere-viewer -S 2.原始全景圖展示 初始化標簽容器 體驗AI代碼助手 代碼解讀復制代碼 // 全景圖的根節點必須要具備寬高 TS引用,創建…

Redis之分布式鎖(3)

這篇文章我們來詳細介紹一下如何正確地基于Redis實現分布式鎖。 基于Redis的分布式鎖實現 組件依賴 首先通過Maven引入Jedis開源組件&#xff0c;在pom.xml文件加入下面的代碼&#xff1a; <dependency><groupId>redis.clients</groupId><artifactId&g…

Java課堂筆記11

三個修飾符 一、abstract&#xff08;抽象&#xff09; 1.抽象方法只能在抽象的類里&#xff0c;只有方法的聲明&#xff0c;沒有方法的實現。&#xff08;沒有{}直接&#xff1b;結尾&#xff09;。 2.abstract修飾的類稱為抽象類。 注意&#xff1a;&#xff08;1&#x…

Linux 核心知識點整理(高頻考點版)

一、編譯與工具鏈 GCC 編譯流程 四階段&#xff1a;預處理&#xff08;-E&#xff0c;處理頭文件 / 宏&#xff09;→ 編譯&#xff08;-S&#xff0c;生成匯編&#xff09;→ 匯編&#xff08;-c&#xff0c;生成目標文件&#xff09;→ 鏈接&#xff08;生成可執行程序&…

輕量化社交管理方案:Skout與云手機的巧妙搭配

在移動社交時代&#xff0c;許多用戶開始嘗試通過多賬號管理來拓展社交圈層。近期測試了Skout社交平臺與亞矩陣云手機的搭配使用&#xff0c;發現這個組合為輕量級社交賬號管理提供了一個值得關注的解決方案。 基礎功能介紹 這套組合的核心優勢在于&#xff1a; 通過云手機實…

ETL連接器好用嗎?如何實現ETL連接?

目錄 一、ETL連接器的功能和優勢 1. 數據抽取能力 2. 數據轉換功能 3. 數據加載功能 4. 優勢總結 二、實現ETL連接的步驟 1. 需求分析 2. 選擇合適的ETL連接器 3. 配置數據源和目標系統 4. 設計ETL流程 5. 開發和測試ETL任務 6. 部署和監控ETL任務 三、ETL連接器在…

uniapp實現聊天中的接發消息自動滾動、消息定位和回到底部

前言 前言無需多言&#xff0c;想必大家對聊天軟件的功能已經很熟悉&#xff0c; 這里不做過多贅述&#xff0c;筆者通過uniapp實現聊天中的接發消息自動滾動、消息定位和回到底部。 代碼實現 <template><view class"chat-container"><!-- 消息列表…

MyBatisMyBatis plus

整合 MyBatis 到 Spring 或 Spring Boot 項目中&#xff0c;可以極大地簡化開發流程&#xff0c;尤其是當使用 Spring Boot 時&#xff0c;它提供了自動配置功能&#xff0c;使得集成更加簡便。 在 Spring Boot 中整合 MyBatis 1. 添加依賴 首先&#xff0c;在 pom.xml 文件中…

Stable Diffusion 實戰-手機壁紙制作 第二篇:優化那些“崩臉”和“馬賽克”問題,讓圖像更加完美!

歡迎回來!在《StableDiffusion實戰-手機壁紙制作》系列的第一篇中,我們成功完成了基礎操作,制作出了令人炫目的手機壁紙。 今天,我們將進入一個更高階的領域——優化處理。因為誰不想讓生成的藝術品更完美呢?尤其是避免“崩臉”和“馬賽克”這種讓人抓狂的問題! 創作的路…

408第一季 - 數據結構 - B樹與B+樹

B樹 性質 可以看見一個節點可以有多個數字了 然后也滿足左小右大的特征 然后所有的葉子節點都在同一層&#xff0c;然后2個數字的節點就可以有3個分支 然后呢&#xff0c;每個節點里面到底有幾個數字是有規定的公式的 就這個公式&#xff0c;m是5階的&#xff0c;算出來是2和…

SSRF5 Gopher 協議對內網 Web 服務進行 sql 注入 GET 類型和POST類型

實驗環境&#xff1b; Centos7.6上同時安裝sqli-lib和pikachu 一.Gopher 協議對內網 Web 服務進行 sql 注入 GET 類型 我們先訪問sqli-lib第1關 然后我們構造URL&#xff1a; http://192.168.112.12/pikachu-master/vul/ssrf/ssrf_curl.php?urlhttp://192.168.112.12/sql…

Python打卡DAY31

DAY31&#xff1a;文件的規范拆分和寫法 恩師浙大疏錦行 知識點&#xff1a; 規范的文件命名規范的文件夾管理機器學習項目的拆分編碼格式和類型注解 一、機器學習項目流程&#xff1a; 1、數據加載&#xff1a;從文件、數據庫、API 等獲取原始數據。 - 命名參考&#xff1a;…

字符串大數 -減法

描述 以字符串的形式讀入兩個數字&#xff0c;編寫一個函數計算它們的和&#xff0c;以字符串形式返回。 代碼實現 大小判斷&#xff1a;a - b 與 b - a 的絕對值相等將大的數放前面&#xff0c;抽離出結果的符號 import random s, t str(random.randint(1000, 9999)), s…

android google tts如何不聯網內部預置多國語音包

在內置Google GMS服務的設備中&#xff0c;可以正常使用TTS&#xff0c;并且可以聯網下載多國的語音包。然而&#xff0c;對于未通過GMS認證&#xff0c;只能使用基礎的TTS英語播報&#xff0c;而且聯網后是無法下載語音包的&#xff0c;會提示需要google service。本文基于以上…

Java 全棧開發學習:從后端基石到前端靈動的成長之路

目錄 一、開篇&#xff1a;與 Java 全棧的初遇 二、后端學習&#xff1a;SpringBoot 構建穩健基石 &#xff08;一&#xff09;SpringBoot3 入門&#xff1a;簡約而不簡單的啟程 &#xff08;二&#xff09;Spring Boot Web 應用開發&#xff1a;構建交互橋梁 &#xff08;…

AquaCrop模型源代碼分析、模型優化與敏感性分析、未來氣候變化影響分析

AquaCrop是由世界糧食及農業組織&#xff08;FAO&#xff09;開發的一個先進模型&#xff0c;旨在研究和優化農作物的水分生產效率。這個模型在全球范圍內被廣泛應用于農業水管理&#xff0c;特別是在制定農作物灌溉計劃和應對水資源限制方面顯示出其強大的實用性。AquaCrop 不…

開源模型應用落地-讓AI更懂你的每一次交互-mem0-QDrant-Streamlit(一)

一、前言 在人工智能迅猛發展的今天,大型語言模型(LLM)已經成為各行各業的重要工具。然而,盡管這些模型在生成文本、理解語義等方面表現出色,但它們仍然面臨一個關鍵挑戰——缺乏持久的記憶能力。傳統的對話系統往往只能基于當前對話輪次進行回應,無法有效保留和利用歷史…

RPC - Response模塊

Requestor 類是一個請求-響應管理器&#xff0c;負責發送請求并處理響應&#xff0c;支持三種交互模式&#xff1a;同步、異步和回調。它跟蹤所有發出的請求&#xff0c;當響應到達時將其匹配到對應的請求并進行處理。 newDescribe 函數解析 newDescribe 函數負責創建和注冊一…

超高速10G采集卡

超高速10G采集卡是一款高端14位數據采集平臺&#xff0c;旨在滿足最具挑戰性的測量環境。 特性: 單通道和雙通道操作 單通道10GSPS或雙通道5GSPS 7 GByte/s持續數據傳輸速率開放式FPGA支持實時DSP 脈沖檢測固件選項波形平均固件選項 特征 單通道和雙通道工作模式雙通道5G…

One-Hot、BOW、TF-IDF、N-Gram區別

1. One-Hot Encoding (獨熱編碼) 核心思想&#xff1a; 為語料庫&#xff08;所有文檔的集合&#xff09;中的每個唯一單詞創建一個維度。對于一個特定的單詞&#xff0c;在其對應的維度上標記為1&#xff0c;在所有其他維度上標記為0。 表示&#xff1a; 一個非常長的二進制向…