C++11QT復習 (五)

文章目錄

    • **Day6-2 成員訪問運算符重載(2025.03.25)**
    • **1. 復習**
    • **2. 成員訪問運算符重載**
      • **2.1 箭頭運算符 (`->`) 重載**
        • **(1) 語法**
      • **2.2 解引用運算符 (`*`) 重載**
        • **(1) 語法**
    • **3. 代碼分析**
      • **3.1 代碼結構**
      • **3.2 代碼解析**
        • **(1) `Data` 類**
        • **(2) `SecondLayer` 類**
        • **(3) `ThirdLayer` 類**
      • **3.3 運行 `test()` 方法**
    • **4. 總結**

Day6-2 成員訪問運算符重載(2025.03.25)

1. 復習

在上一節中,我們學習了 C++ 中的 輸入輸出流運算符重載(<<>> 以及 下標運算符 [] 和函數調用運算符 () 的重載。本節我們將重點學習 成員訪問運算符(->*)的重載


2. 成員訪問運算符重載

C++ 允許用戶自定義類的成員訪問方式,其中 ->(箭頭運算符)和 *(解引用運算符)是最常見的運算符之一。它們通常用于模擬智能指針或多層指針訪問。

2.1 箭頭運算符 (->) 重載

(1) 語法
class A {
public:B* operator->();
};

作用

  • 允許 A 類的對象 像指針一樣訪問 B 類的成員
  • 典型用途是在 封裝指針 的類(如智能指針)中重載 operator->,使得用戶無需手動解引用即可訪問目標對象的成員。

注意事項:

  1. 返回值必須是一個指針或者引用,否則無法繼續訪問成員變量或函數。
  2. 如果返回的是對象的引用,則可以實現多層 -> 重載。
  3. operator-> 不能改變調用對象自身,因此通常 不應該聲明為 const 成員函數

2.2 解引用運算符 (*) 重載

(1) 語法
class A {
public:B& operator*();
};

作用

  • 允許 A 類的對象 像指針一樣進行解引用
  • 常見于智能指針的實現,使 *ptr 直接返回對象的引用,方便訪問其成員。

注意事項:

  1. 返回值一般是引用(如 B&),這樣不會產生額外的拷貝。
  2. 適用于 封裝指針 的類,如智能指針或代理類。

3. 代碼分析

#include <iostream> 
using namespace std;class Data
{
public:Data(int data = 0):_data(data){cout << "Data(int data = 0)" << endl;}~Data(){cout << "~Data()" << endl; }int getData() const{return _data;}
private:int _data;
};class SecondLayer
{
public:SecondLayer(Data* pData):_pData(pData){cout << "SecondLayer(Data* pData)" << endl;}//重載 -> 運算符Data* operator->(){return _pData;}//解引用重載運算符Data& operator*(){return *_pData;}~SecondLayer(){cout << "~SecondLayer()" << endl;if (_pData){delete _pData;_pData = nullptr;}}private:Data* _pData;
};class ThirdLayer
{
public:ThirdLayer(SecondLayer* pSecond):_pSecond(pSecond){cout << "ThirdLayer(SecondLayer* pSecond)" << endl;}//重載 -> 運算符SecondLayer& operator->() {return *_pSecond;}~ThirdLayer(){cout << "~ThirdLayer()" << endl;if (_pSecond){delete _pSecond;_pSecond = nullptr;}}private:SecondLayer* _pSecond;
};void test()
{/*Data* data = new Data(1);SecondLayer* second = new SecondLayer(data);ThirdLayer* third = new ThirdLayer(second);*/SecondLayer second(new Data(10));//棧對象//A類的對象調用B類的成員函數/*cout << "&second : " << &second << endl;cout << "second.operator->() :" << second.operator->() << endl;*///  重載operator->  cout << "second.operator->()->getData() :" << second.operator->()->getData() << endl;cout << "second->getData() :" << second->getData() << endl;//  重載operator* cout << "(*second).getData()" << (*second).getData() << endl;ThirdLayer third(new SecondLayer(new Data(30)));//棧對象cout << "third->getData() : " << third->getData() << endl;//還原cout << "third.operator->().operator->()->getData()" << third.operator->().operator->()->getData();
}int main(int argc, char** argv)
{test();test();return 0;
}

3.1 代碼結構

上面的代碼實現了一個 三層封裝 的指針代理類,分別是:

  • Data:數據類,包含一個 _data 成員變量。
  • SecondLayer:封裝 Data* 指針,并重載 operator->operator*
  • ThirdLayer:封裝 SecondLayer* 指針,并重載 operator->

3.2 代碼解析

(1) Data
class Data
{
public:Data(int data = 0) : _data(data){cout << "Data(int data = 0)" << endl;}~Data(){cout << "~Data()" << endl;}int getData() const{return _data;}
private:int _data;
};
  • Data 類封裝了一個 int 類型的數據 _data,提供了 getData() 方法用于獲取數據值。
  • 構造函數、析構函數用于跟蹤對象的創建和銷毀。

(2) SecondLayer
class SecondLayer
{
public:SecondLayer(Data* pData) : _pData(pData){cout << "SecondLayer(Data* pData)" << endl;}// 重載 -> 運算符Data* operator->(){return _pData;}// 解引用運算符 *Data& operator*(){return *_pData;}~SecondLayer(){cout << "~SecondLayer()" << endl;if (_pData){delete _pData;_pData = nullptr;}}private:Data* _pData;
};
  • 封裝 Data* 指針,并提供訪問 Data 成員的方式
  • operator->() 返回 _pData 指針,使得 SecondLayer 對象 可以像指針一樣使用 -> 訪問 Data 的方法
  • operator*() 返回 _pData 所指向的 Data 對象的引用,使 *second 直接返回 Data 對象。

示例:

SecondLayer second(new Data(10));
cout << second->getData() << endl;  // 等價于 second.operator->()->getData()
cout << (*second).getData() << endl; // 等價于 second.operator*().getData()

(3) ThirdLayer
class ThirdLayer
{
public:ThirdLayer(SecondLayer* pSecond) : _pSecond(pSecond){cout << "ThirdLayer(SecondLayer* pSecond)" << endl;}// 重載 -> 運算符SecondLayer& operator->(){return *_pSecond;}~ThirdLayer(){cout << "~ThirdLayer()" << endl;if (_pSecond){delete _pSecond;_pSecond = nullptr;}}private:SecondLayer* _pSecond;
};
  • ThirdLayer 封裝了 SecondLayer* 指針,并提供 operator->() 使其 可以像 SecondLayer 一樣使用 -> 訪問 Data 的方法
  • 實現兩層 -> 重載,使得 ThirdLayer 可以連續訪問 Data 成員。

示例:

ThirdLayer third(new SecondLayer(new Data(30)));
cout << third->getData() << endl;  // 等價于 third.operator->().operator->()->getData()

3.3 運行 test() 方法

void test()
{SecondLayer second(new Data(10));cout << "second->getData() :" << second->getData() << endl;cout << "(*second).getData()" << (*second).getData() << endl;ThirdLayer third(new SecondLayer(new Data(30)));cout << "third->getData() : " << third->getData() << endl;cout << "third.operator->().operator->()->getData() : " << third.operator->().operator->()->getData();
}

輸出:

Data(int data = 0)
SecondLayer(Data* pData)
second->getData() : 10
(*second).getData() : 10
Data(int data = 0)
SecondLayer(Data* pData)
ThirdLayer(SecondLayer* pSecond)
third->getData() : 30
third.operator->().operator->()->getData() : 30
~ThirdLayer()
~SecondLayer()
~Data()
~SecondLayer()
~Data()
  • SecondLayer 允許訪問 Data 對象。
  • ThirdLayer 允許訪問 SecondLayer,最終可訪問 Data
  • 多層指針訪問的代理模式生效,并且析構時正確釋放了內存。

4. 總結

運算符作用適用場景返回值類型
operator->()允許對象像指針一樣訪問成員智能指針、代理類指針或引用
operator*()允許對象像指針一樣解引用智能指針、代理類引用

關鍵點:

  1. operator->() 需要返回指針或引用,可以連續調用 ->
  2. operator*() 需要返回對象的引用,避免拷貝,提高性能。
  3. 適用于封裝指針的類,如智能指針和代理類

本節學習了 成員訪問運算符 ->* 的重載,掌握它們的用法可以更好地理解 智能指針代理模式

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

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

相關文章

簡歷含金量的描述和注意事項!

背景 最近&#xff0c;在公司負責后端相關面試&#xff0c;簡歷看了不下 50 份&#xff0c;面試 10&#xff0c;純手碼 2000 多字&#xff0c;說說我對簡歷的看法&#xff0c;希望給大家一點啟發。 教育經歷 在眾多求職面試中&#xff0c;我發現多數求職者容易忽視教育背景的…

cellnet框架概述

cellnet框架是一個?高性能、組件化、多協議支持?的開源服務器網絡庫&#xff0c;專注于游戲服務器、分布式的多進程通信等場景的開發。 一、核心特性 ?支持多個主流協議&#xff0c;包括TCP、UDP、HTTP、WebSocket。并且抽象底層協議差異&#xff0c;統一網絡連接管理?。 …

【加密社】如何創建自己的幣圈工具站

需要準備的工作 1.域名 2.服務器 周末的時候主要弄了快訊這方面的代碼 我這里用的是星球日報的api&#xff0c;也可以訂閱他們的rss&#xff0c;這部分在github上是開源的 https://github.com/ODAILY 我這里用的是WordPressonenav主題&#xff0c;然后用小工具在主頁展示&am…

Docker學習筆記(十一)宿主機無法鏈接宿主機問題處理

故障排查優先級排序 服務狀態 → 2. 端口監聽 → 3. 防火墻 → 4. 權限配置 → 5. 網絡路由 &#xff08;按此順序可覆蓋95%的常見問題?15&#xff09; mysql鏡像啟動命令&#xff1a; docker run -p 3306:3306 --restartalways --name mysqlv8 -e MYSQL_ROOT_PASSWORDCd…

力扣:回溯算法

組合I class Solution {List<List<Integer>> result new ArrayList(); // 所有結果集List<Integer> list new ArrayList(); // 當前結果集public List<List<Integer>> combine(int n, int k) {dfs(n, k, 1);return result;}public void dfs(i…

華為HCIE鴻蒙應用開發認證靠譜嗎?

在萬物互聯時代&#xff0c;智能終端設備的多樣性與協同需求催生了操作系統的革新。華為HarmonyOS&#xff08;鴻蒙系統&#xff09;憑借其分布式架構與全場景能力&#xff0c;正成為打破設備邊界、重塑用戶體驗的核心技術底座。HCIE鴻蒙應用開發認證作為華為認證體系的頂級資質…

23種設計模式-原型(Prototype)設計模式

原型設計模式 &#x1f6a9;什么是原型設計模式&#xff1f;&#x1f6a9;原型設計模式的特點&#x1f6a9;原型設計模式的結構&#x1f6a9;原型設計模式的優缺點&#x1f6a9;原型設計模式的Java實現&#x1f6a9;代碼總結&#x1f6a9;總結 &#x1f6a9;什么是原型設計模式…

Oracle-rman restore遭遇RMAN-03002與ORA-19563

文章目錄 在原DB上檢查是否有重復的文件名&#xff1a;查看rman恢復的日志修正重名部分重新執行rman恢復結論&#xff1a; 在 RMAN 恢復過程中&#xff0c;遇到RMAN-03002連同ORA-19563:錯誤。 操作是將 Oracle 10.0.5的數據庫備份從 RMAN備份恢復到另一臺測試主機的同一個目錄…

運維網絡排查工具介紹與使用

作為一名運維工程師&#xff0c;日常工作中最令人頭疼的莫過于各種網絡故障。在過去一年半的運維生涯中&#xff0c;我積累了豐富的網絡故障排查經驗&#xff0c;今天就來和大家分享一下如何運用抓包工具&#xff08;Wireshark、tcpdump&#xff09;和網絡排查工具&#xff08;…

解決vscode終端和本地終端python版本不一致的問題

&#x1f33f; 問題描述 本地終端&#xff1a; vscode終端&#xff1a; 別被這個給騙了&#xff0c;繼續往下看&#xff1a; 難怪我導入一些包的時候老提示找不到&#xff0c;在本地終端就不會這樣&#xff0c;于是我嚴重懷疑vscode中的python版本和終端不一樣&#xff0c…

Sublime全局搜索快捷鍵Ctrl+Shift+F不能使用解決

問題描述&#xff1a; 在安裝好Sublime后&#xff0c;我們使用快捷鍵進行全局搜索&#xff0c;發現沒有反應&#xff0c;但是中文輸入變成了繁體。 解決方案&#xff1a; 如截圖&#xff0c;在關閉簡繁切換的快捷鍵或者換成其他的就行

海康HTTP監聽報警事件數據

http監聽接收報警事件數據 海康獲取設備報警事件數據兩種方式&#xff1a; 1、sdk 布防監聽報警事件數據,服務端布防。&#xff08;前面文章有示例&#xff09; 2、http監聽接收報警事件數據&#xff0c;設備直接推送。 http監聽接收報警事件數據&#xff0c;服務端可以使用n…

Python----計算機視覺處理(Opencv:圖像邊緣檢測:非極大值抑制,雙閾值篩選)

一、 高斯濾波 邊緣檢測本身屬于銳化操作&#xff0c;對噪點比較敏感&#xff0c;所以需要進行平滑處理。這里使用的是一個5*5的高斯 核對圖像進行消除噪聲。 二、計算圖像的梯度和方向 三、非極大值抑制 在得到每個邊緣的方向之后&#xff0c;其實把它們連起來邊緣檢測就算完了…

Maven工具學習使用(四)——倉庫

倉庫分類 對于Mavne來說,倉庫只分為兩類:本地倉庫和遠程倉庫。當Maven根據坐標查詢尋找構件的時候,它首先會查看本地倉庫,如果本地倉庫存在此構件,則直接使用;如果本地倉庫不存在此構件,或者需要查看是否有更新的構件版本,Maven就會去遠程倉庫查找,發現需要的構件之后…

Axure PR 9.0(發音:Ack-sure)原型圖工具入門教程:鏈接交互

文章目錄 引言Axure? RP 9I Axure RP9入門介紹元件庫對兩個元件進行連接頁面:導航視圖、概要母版交互II 鏈接交互從A頁面跳轉到B頁面返回之前的頁面see also引言 【 產品原型圖】核心價值和實際應用場景:可視化需求,統一團隊理解 https://blog.csdn.net/z929118967/articl…

docker遠程debug

1. 修改 Java 啟動命令 在 Docker 容器中啟動 Java 程序時&#xff0c;需要添加 JVM 調試參數&#xff0c;jdk8以上版本 java -agentlib:jdwptransportdt_socket,servery,suspendn,address*:5005 -jar your-app.jar jdk8及以下版本&#xff1a; java -Xdebug -Xrunjdwp:tra…

K8S學習之基礎五十四:jenkins新建測試流水線

jenkins新建測試流水線 新建任務 node(testak) {stage(第1步:從gitee上下載源代碼) {git url: "https://gitee.com/akang007/jenkins-sample"script {build_tag sh(returnStdout: true, script: git rev-parse --short HEAD).trim()}}stage(第2步&#xff1a;基…

SylixOS 中 select 原理及使用分析

1、select接口簡介 1.1 select接口使用用例 select 是操作系統多路 I/O 復用技術實現的方式之一。 select 函數允許程序監視多個文件描述符&#xff0c;等待所監視的一個或者多個文件描述符變為“準備好”的狀態。所謂的”準備好“狀態是指&#xff1a;文件描述符不再是阻塞狀…

Spring WebFlux之ServerWebExchange

ServerWebExchange 是 Spring WebFlux 中的一個核心接口&#xff0c;用于表示服務器端處理的 HTTP 請求和響應。它封裝了請求和響應的所有信息&#xff0c;并提供了相應的方法來操作這些信息。ServerWebExchange 在響應式編程模型中扮演著關鍵角色&#xff0c;支持非阻塞、異步…

Flutter 常見錯誤和坑

1. 狀態管理問題 StatefulWidget 生命周期誤用 // 錯誤&#xff1a;在 build 方法中修改狀態 override Widget build(BuildContext context) {setState(() { counter; }); // 會導致無限重建循環return Text($counter); }// 正確&#xff1a;在事件處理中修改狀態 Widget bui…