C++11:引用限定符

来源:https://www.cnblogs.com/crossoverpptx/archive/2023/01/01/17017737.html
-Advertisement-
Play Games

C++中有左值和右值的概念。其實,左值和右值的區分也同樣適用於類對象,本文中將左值的類對象稱為左值對象,將右值的類對象稱為右值對象。 1. C++11:引用限定符 預設情況下,對於類中用 public 修飾的成員函數,既可以被左值對象調用,也可以被右值對象調用。舉個例子: #include <ios ...


C++中有左值和右值的概念。其實,左值和右值的區分也同樣適用於類對象,本文中將左值的類對象稱為左值對象,將右值的類對象稱為右值對象。

1. C++11:引用限定符

預設情況下,對於類中用 public 修飾的成員函數,既可以被左值對象調用,也可以被右值對象調用。舉個例子:

#include <iostream>
using namespace std;

class demo {
public:
    demo(int num):num(num){}
    int get_num(){
        return this->num;
    }
private:
    int num;
};

int main() {
    demo a(10);
    cout << a.get_num() << endl;
    cout << move(a).get_num() << endl;
    return 0;
}

可以看到,demo 類中的 get_num() 成員函數既可以被 a 左值對象調用,也可以被 move(a) 生成的右值 demo 對象調用,運行程式會輸出兩個 10。

某些場景中,我們可能需要限制調用成員函數的對象的類型(左值還是右值),為此 C++11 新添加了引用限定符。所謂引用限定符,就是在成員函數的後面添加 "&" 或者 "&&",從而限制調用者的類型(左值還是右值)。
修改上面程式如下:

#include <iostream>
using namespace std;

class demo {
public:
    demo(int num):num(num){}
    int get_num()&{
        return this->num;
    }
private:
    int num;
};

int main() {
    demo a(10);
    cout << a.get_num() << endl;          // 正確
    //cout << move(a).get_num() << endl;  // 錯誤
    return 0;
}

和之前的程式相比,我們僅在 get_num() 成員函數的後面添加了 "&",它可以限定調用該函數的對象必須是左值對象。因此第 17 行代碼中,move(a) 生成的右值對象是不允許調用 get_num() 函數的。
同理,我們再次修改程式:

#include <iostream>
using namespace std;

class demo {
public:
    demo(int num):num(num){}
    int get_num()&&{
        return this->num;
    }
private:
    int num;
};

int main() {
    demo a(10);
    //cout << a.get_num() << endl;      // 錯誤
    cout << move(a).get_num() << endl;  // 正確
    return 0;
}

和先前程式不同的是,get_num() 函數後根有 "&&" 限定符,它可以限定調用該函數的對象必須是一個右值對象。

註意:引用限定符不適用於靜態成員函數和友元函數。

2. const和引用限定符

我們知道,const 也可以用於修飾類的成員函數,我們習慣稱為常成員函數,例如:

class demo{
public:
    int get_num() const;
}

這裡的 get_num() 就是一個常成員函數。const 和引用限定符修飾類的成員函數時,都位於函數的末尾。C++11 標準規定,當引用限定符和 const 修飾同一個類的成員函數時,const 必須位於引用限定符前面。
需要註意的一點是,當 const && 修飾類的成員函數時,調用它的對象只能是右值對象;當 const & 修飾類的成員函數時,調用它的對象既可以是左值對象,也可以是右值對象。無論是 const && 還是 const & 限定的成員函數,內部都不允許對當前對象做修改操作。

舉個例子:

#include <iostream>
using namespace std;

class demo {
public:
    demo(int num,int num2) :num(num),num2(num2) {}
    //左值和右值對象都可以調用
    int get_num() const &{
        return this->num;
    }
    //僅供右值對象調用
    int get_num2() const && {
        return this->num2;
    }
private:
    int num;
    int num2;
};

int main() {
    demo a(10,20);
    cout << a.get_num() << endl;        // 正確
    cout << move(a).get_num() << endl;  // 正確
   
    //cout << a.get_num2() << endl;     // 錯誤 
    cout << move(a).get_num2() << endl; // 正確
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 卸載mysql教程: (261條消息) 如何徹底卸載 MySQL ,再可重新安裝 MySQL_Cavalier_01的博客-CSDN博客_如何卸載mysql重新安裝 安裝mysql5.7.19: 首先,去官網下載5.7.19壓縮包然後解壓; MySQL :: Download MySQL Commu ...
  • 一:背景 1. 講故事 上一篇寫完了之後,馬上就有朋友留言對記錄行的 8060byte 限制的疑惑,因為他的表記錄存儲了大量的文章,存儲文章的欄位類型用的是 nvarchar(max),長度很顯然是超過 8060byte 的,請問這個底層是怎麼破掉 8060byte 的限制的? 說實話這是一個好問題 ...
  • 為了應對大流量,現代應用/中間件通常採用分散式部署,此時不得不考慮 CAP 問題。ZooKeeper(後文簡稱 ZK)是面向 CP 設計的一個開源的分散式協調框架,將那些複雜且容易出錯的分散式一致性服務封裝起來,構成一個高效可靠的原語集,並以一系列簡單易用的介面提供給用戶使用,分散式應用程式可以基於... ...
  • 力扣104 求二叉樹的最大深度 題目: 給定一個二叉樹,找出其最大深度。 二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。 說明: 葉子節點是指沒有子節點的節點。 示例 給定二叉樹 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回它的最大深度 3 ...
  • 力扣100 相同的樹 題目: 給你兩棵二叉樹的根節點 p 和 q ,編寫一個函數來檢驗這兩棵樹是否相同。 如果兩個樹在結構上相同,並且節點具有相同的值,則認為它們是相同的。 示例 1: 輸入:p = [1,2,3], q = [1,2,3] 輸出:true 示例 2: 輸入:p = [1,2], q ...
  • RequestMappingHandlerAdapter是Spring Web MVC中針對@Controller和@RequestMapping體系的處理器適配器,本文對RequestMappingHandlerAdapter的組成、初始化以及同步請求處理流程進行詳細梳理和總結。 ...
  • 家居網購項目實現012 以下皆為部分代碼,詳見 https://github.com/liyuelian/furniture_mall.git 29.功能27-Ajax檢驗註冊名 29.1需求分析/圖解 用戶註冊時,後端通過驗證,提示用戶當前輸入的用戶名是否可用。 29.2思路分析 29.3代碼實現 ...
  • JZ76 刪除鏈表中重覆的結點 題目 在一個排序的鏈表中,存在重覆的結點,請刪除該鏈表中重覆的結點,重覆的結點不保留,返回鏈表頭指針。 例如,鏈表 1->2->3->3->4->4->5 處理後為 1->2->5 方法1 哈希表進行刪除 思路 演算法實現 LinkedHashMap實現順序插入,不過查 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...