Effective C++ 條款07:為多態基類聲明virtual析構函數

Effective C++ 條款07:為多態基類聲明virtual析構函數


核心思想當通過基類指針刪除派生類對象時,如果基類沒有虛析構函數,會導致派生類資源泄漏。因為此時只會調用基類的析構函數,而不會調用派生類的析構函數。

?? 1. 問題場景:非虛析構函數導致資源泄漏
class Base {
public:Base() { std::cout << "Base構造\n"; }~Base() { std::cout << "Base析構\n"; } // 非虛析構函數
};class Derived : public Base {
public:Derived() : data(new int(42)) { std::cout << "Derived構造\n"; }~Derived() { delete data; // 釋放資源std::cout << "Derived析構\n"; }
private:int* data; // 派生類獨占資源
};int main() {Base* pb = new Derived(); // 基類指針指向派生類對象delete pb; // 僅調用Base::~Base() → 內存泄漏!
}

輸出結果

Base構造
Derived構造
Base析構

問題Derived的資源data未被釋放 → 內存泄漏!


? 2. 解決方案:聲明虛析構函數
class Base {
public:Base() { std::cout << "Base構造\n"; }virtual ~Base() { std::cout << "Base析構\n"; } // 虛析構函數
};class Derived : public Base { /* 實現同上 */ };int main() {Base* pb = new Derived();delete pb; // 正確調用派生類析構函數
}

輸出結果

Base構造
Derived構造
Derived析構  // 先調用派生類析構函數
Base析構    // 再調用基類析構函數

🔍 3. 關鍵原則
場景析構函數要求原因
多態基類(有虛函數)必須virtual確保通過基類指針刪除派生類對象時,正確調用派生類析構函數
非多態基類(無虛函數)不應virtual避免虛表指針帶來的空間開銷(條款7指出每個對象增加4-8字節)
STL容器(如std::string禁止繼承標準庫類的析構函數均為非虛,通過基類指針刪除派生類對象會導致未定義行為

?? 4. 錯誤實踐:繼承STL容器類
class MyString : public std::string { 
public:~MyString() { std::cout << "MyString析構\n"; }
};int main() {std::string* ps = new MyString(); delete ps; // 未定義行為!std::~string非虛
}

結果MyString::~MyString()不會被調用 → 潛在資源泄漏!


💎 5. 純虛析構函數的特殊用法

使類成為抽象類,同時仍需要提供實現

class AbstractBase {
public:virtual ~AbstractBase() = 0; // 純虛聲明
};
AbstractBase::~AbstractBase() {}  // 必須提供實現class Concrete : public AbstractBase {
public:~Concrete() override { std::cout << "Concrete析構\n"; }
};int main() {AbstractBase* p = new Concrete();delete p; // 正確調用鏈:Concrete::~ → AbstractBase::~ 
}

總結:多態基類虛析構三原則

  1. 多態基類必須聲明虛析構函數
    virtual ~Base() = default;
  2. 非多態基類不要聲明虛析構函數
    避免無謂的虛函數表開銷
  3. 禁止繼承無虛析構函數的類(如STL容器)
    組合優于繼承:將目標類作為成員變量而非基類

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

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

相關文章

C++進階—C++11

第一章&#xff1a;C11簡介 在2003年C標準委員會曾經提交了一份技術勘誤表(簡稱TC1)&#xff0c;使得C03這個名字已經取代了C98稱為C11之前的最新C標準名稱。不過由于C03(TC1)主要是對C98標準中的漏洞進行修復&#xff0c;語言的核心部分則沒有改動&#xff0c;因此人們習慣性…

把振動數據轉成音頻并播放

把振動數據轉聲音并播放 1、實現流程 安裝第三方庫: pip install numpy==1.23.5 pip install scipy==1.10.1 pip install sounddevice==0.4.6流程: 1、導入振動數據 2、數據歸一化到[-1, 1]范圍 3、重采樣到44.1kHz 4、播放音頻 5、保存音頻為WAV文件(可選)2、代碼示例 …

ServBay 1.15.0 更新,擁抱 Bun Deno 新生態

歷時一個月&#xff0c;ServBay迎來了1.15.0的更新。我們始終堅信&#xff0c;一個優秀的本地開發環境&#xff0c;不僅要穩定、高效&#xff0c;更要緊跟技術的演進脈搏。ServBay 的使命是為開發者掃清開發環境配置的障礙&#xff0c;讓您能聚焦于創造本身。 本次ServBay 1.1…

Java設計模式-通俗舉例

設計模式就像做菜的食譜&#xff0c;告訴我們遇到常見問題時該用什么"烹飪方法"。今天我就用最生活化的例子&#xff0c;帶大家輕松掌握23種設計模式的精髓。一、創建型模式&#xff08;5種&#xff09;&#xff1a;怎么"造東西"1. 單例模式&#xff1a;公…

【跟我學YOLO】YOLO12(3)訓練自己的數據集

歡迎關注『跟我學 YOLO』系列 【跟我學YOLO】&#xff08;1&#xff09;YOLO12&#xff1a;以注意力為中心的物體檢測 【跟我學YOLO】&#xff08;2&#xff09;YOLO12 環境配置與基本應用 【跟我學YOLO】&#xff08;3&#xff09;YOLO12 訓練自己的數據集 【跟我學YOLO】&…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 微博輿情分析實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解微博輿情分析實現 視頻在線地址&#xff1…

【C++】手搓一個STL風格的vector容器

TOC(手搓一個STL風格的vector容器) 手搓一個STL風格的vector容器 github地址 有夢想的電信狗 0. 前言&#xff1a;動態數組的工程實踐 ? 在C標準庫中&#xff0c;vector容器作為最核心的序列式容器&#xff0c;其設計融合了動態數組的高效性與安全性。本文將通過完整實現…

24. 了解過 webp 嗎

總結 一種圖片格式 一、什么是 WebP&#xff1f; WebP&#xff08;發音為 “weppy”&#xff09;是由 Google 推出的一種現代圖片格式&#xff0c;支持有損壓縮和無損壓縮&#xff0c;旨在提供更小的文件體積和更高質量的圖像顯示。 它兼容常見的圖片功能&#xff0c;如&#…

【Unity筆記】Unity Camera.cullingMask 使用指南:Layer 精準控制、XR 多視圖與性能提升

Unity Camera.cullingMask 使用指南&#xff1a;Layer 精準控制、XR 多視圖與性能提升 關鍵詞&#xff1a;Unity、Camera、Culling Mask、Layer 控制、XR 渲染分離、UI 顯隱、性能優化 特別說明&#xff1a; 本文為近期項目所遇問題的總結&#xff0c;僅純文字記錄&#xff0c;…

攜帶參數的表單文件上傳 axios, SpringBoot

頁面上的表單如上圖, 點擊確定按鈕需要把參數統一傳給后端.前端代碼:表單的提交方法const submit async () > {const formData new FormData();formData.append("bookName", bookForm.value.bookName);formData.append("author", bookForm.value.auth…

黑馬JavaWeb【復習到哪更新到哪】

登錄認證&#xff08;復習Javaweb的登錄校驗&#xff09; 登錄功能 思路就是loginController->service層->mapper層&#xff0c;從數據庫中查找username和password是否和前端用戶提交的表單內容一致&#xff0c;一致就登錄成功&#xff0c;否則就返回登錄失敗的信息。 登…

NVMe高速傳輸之擺脫XDMA設計21:PCIe請求模塊設計(下)

在接收到請求總線接口的請求事務后&#xff0c;當請求類型的值為0時&#xff0c;表示通過PCIE硬核的配置管理接口發送請求&#xff0c;由于請求接口的接口和時序與配置管理接口基本一致&#xff0c;因此此時直接將請求接口信號驅動到配置管理接口完成請求的發送&#xff0c;請求…

機器學習sklearn:不純度與決策樹構建

不純度與決策樹構建不純度概念&#xff1a;決策樹通過不純度指標來選擇最佳分割節點和分枝方式不純度衡量節點中樣本類別的混雜程度不純度越低&#xff0c;節點中樣本類別越純凈&#xff0c;擬合效果越好常用不純度指標&#xff1a;信息熵(Entropy)&#xff1a;基于信息論的概念…

rk356x IR紅外發射與接收之NEC協議

紅外接收紅外接收頭解碼器&#xff08;紅外信號解碼&#xff0c;主要是NEC解碼&#xff09;紅外發射器紅外發光二極管晶振NEC編碼組成共32位&#xff08;4bit&#xff09;&#xff1a;由8位用戶碼1 8位用戶碼2 8位命令碼 8位命令碼反碼有時會存在按鍵一直按下的一幀信息&…

C++算法之單調棧

C算法中的單調棧&#xff1a;從入門到實戰指南 大家好&#xff01;今天我們來聊聊C算法中一個超級實用的工具——單調棧。別被名字嚇到&#xff0c;它其實很簡單&#xff0c;就像排隊買奶茶一樣&#xff1a;隊伍總是從矮到高&#xff08;或從高到矮&#xff09;排得整整齊齊&a…

React入門指南——指北指南(第二節)

React 實踐:創建你的第一個待辦事項列表 在前面的章節中,我們學習了 React 的核心概念(組件、Props、State 等)。本節將通過一個實際案例——創建待辦事項列表(Todo List),幫助你鞏固這些概念,并掌握 React 中處理用戶交互、動態數據的基本方法。 案例目標 我們將構…

WAIC看點:可交付AI登場,場景智能、專屬知識將兌現下一代AI價值

7月28日&#xff0c;為期三天的2025世界人工智能大會&#xff08;WAIC 2025&#xff09;在上海落下帷幕。作為全球 AI 領域最受關注的盛會之一&#xff0c;今年 WAIC 聚焦 AI 關鍵命題&#xff0c;圍繞大模型與智能體應用、算力新基建及大數據、智能終端與具身智能、AI金融、AI…

設計模式(十一)結構型:外觀模式詳解

設計模式&#xff08;十一&#xff09;結構型&#xff1a;外觀模式詳解外觀模式&#xff08;Facade Pattern&#xff09;是 GoF 23 種設計模式中的結構型模式之一&#xff0c;其核心價值在于為一個復雜的子系統提供一個統一、簡化的高層接口&#xff0c;從而降低客戶端與子系統…

接口測試核心概念與實踐指南

核心概念什么是接口&#xff1f;軟件不同部分之間進行通信和數據交換的約定或契約。定義了&#xff1a;請求方 (Client/Consumer) 如何調用&#xff08;方法、URL、參數&#xff09;。提供方 (Server/Provider) 如何響應&#xff08;數據結構、狀態碼&#xff09;。雙方需要遵循…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 熱詞數量分析日期統計功能實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解熱詞數量分析日期統計功能實現 視頻在線地…