拷貝構造、移動構造、拷貝賦值、移動賦值

????????最近在學習C++的拷貝構造函數時發現一個問題:在函數中返回局部的類對象時,并沒有調用拷貝構造函數。針對這個問題,查閱了一些資料,這里記錄整理一下。

調用拷貝構造函數的三種情況:

① 用一個類去初始化另一個對象時(初始化的為新對象)

②一個對象作為參數,以值傳遞的方式傳入函數內

③ 返回值作為類對象,函數執行完成返回調用時。

下面寫了一個示例代碼:

#include <iostream>
#include <string>
using namespace std;
class Demo {
public:Demo(string name, int data) : m_name(name), m_data(data) {cout << "默認構造函數" << endl;}Demo(const Demo& other) {cout << "拷貝構造函數" << endl;m_name = other.m_name;m_data = other.m_data;}Demo& operator=(const Demo& other) {cout << "拷貝賦值運算符重載" << endl;m_name = other.m_name;m_data = other.m_data;return *this; //return *this 是為了可以連續賦值}Demo(const Demo&& other) {cout << "移動構造函數" <<  endl;m_name = other.m_name;m_data = other.m_data;}Demo& operator=(const Demo&& other) {cout << "移動賦值運算符重載" << endl;m_name = other.m_name;m_data = other.m_data;return *this;}
private:string m_name;int m_data;
};void test01()
{//默認構造Demo a("zhangsam", 10);Demo b("lisi", 20);//拷貝構造:使用一個類去初始化另一個對象時Demo c = a;//拷貝賦值運算符重載:使用一個類對另一個對象賦值c = b = a;//移動構造。使用右值對象對初始化一個對象時Demo e = move(a);//移動賦值運算符重載:使用一個右值對象對另一個對象賦值e = move(b);
}//當類對象做形參是,調用拷貝構造函數
Demo test02(Demo d1)
{Demo f("wangwu", 30);//返回一個類對象時,這里調用了移動構造函數//這里編譯器默認優化,需要增加-fno-elide-constructor編譯選項,但是調用的確實移動構造函數//原因是,在新的標磚中,當編譯器識別到返回的是一個局部的對象,將自動使用move轉化。//前提是類中自定義了移動構造函數,否則將調用拷貝構造函數return f;
}
int main()
{test01();cout << "-----------" << endl;Demo a1("test", 40);test02(a1);cout << "-----------" << endl;return 0;
}

最開始正常編譯 g++ test.cpp??

執行結果:

? ? ? ? 可以看到,test02函數最后返回一個f對象,但是并沒有調用拷貝構造函數。

①?Demo a1("test", 40);? //默認構造函數

② a1形參傳參 //拷貝構造函數

③ 函數內??Demo f("wangwu", 30); //默認構造函數

④ return f //???未打印任何東西

? ? ? ? 查閱資料后,說是需要增加一個編譯選項 -fno-elide-constructors, 果然增加后,出現了相應的打印。

但是,,為什么是調用的移動構造函數。。。

?再次查閱資料到:當從同類型的右值(亡值(將亡值))或純右值)(C++17前)亡值初始化(直接初始化或者復制初始化)對象時會調用移動構造函數,情況包括:

1、初始化 T a = std::move(b) 或 T a(std::move(b))

2、函數實參傳遞? f(std::move(a)) 其中a的類型是T 且f 是Ret f (T t);

3、函數返回:在像T f() 這樣的函數中的retuen a;,其中a的類型是T, 且T中自定義了移動構造函數。

? ? ? ? 所以,,,函數中的局部類對象其實是一個將亡值??

? ? ? ? 然后又百度了下將亡值的概念和定義:

? ? ? ? 就傳統的理解而言,函數foo的返回值在內部創建然后被賦值給v(外部接收返回值的對象),然后v獲得這個對象時,會將整個temp拷貝一份,然后把temp銷毀。如果這個temp非常大,這將造成大量額外的開銷(這也是c++一直被詬病的問題)。在新的特性里面,會自動檢測這個值是不死局部的,是的話,就直接move()了。用不同的編譯器,不同的開關(debug,relese)結果可能都不一樣。

? ? ? ? 例如,一個函數v = foo(),接收返回值的v是一個左值,foo()返回的值也就是一個右值(也是純右值)。但是v可以被別的變量捕獲到,而foo()產生的那個返回值作為一個臨時變量,一旦被v賦值后,將立即被銷毀,無法獲取,也不能修改。

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

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

相關文章

【數據結構與算法 | 基礎篇 | 隊列篇】力扣102, 107

1. 力扣102 : 二叉樹的層序遍歷 (1). 題 給你二叉樹的根節點 root &#xff0c;返回其節點值的 層序遍歷 。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 示例 1&#xff1a; 輸入&#xff1a;root [3,9,20,null,null,15,7] 輸出&#xff1a;[[3]…

對于高速信號完整性,一塊聊聊啊(18)

本文摘錄一篇Allegro進行后仿真的完整流程,可能allegro版本有點老,但整個過程還是描述比較詳細的。 目錄 1、獲取IBIS模型 1.1模型下載 1.2檢查IBIS模型 1.3IBIS轉換為DML 1.4保存DML模型 2、仿真準備 2.1疊層設置 2.2電源網格設置 2.3仿真庫配置 3、仿真 3.1拓撲…

刷爆leetcode第六期

題目一 用隊列實現棧 請你僅使用兩個隊列實現一個后入先出&#xff08;LIFO&#xff09;的棧&#xff0c;并支持普通棧的全部四種操作&#xff08;push、top、pop 和 empty&#xff09;。 實現 MyStack 類&#xff1a; void push(int x) 將元素 x 壓入棧頂。 int pop() 移除…

【漏洞復現】大華智能物聯綜合管理平臺 fastjson遠程代碼執行漏洞

0x01 產品簡介 大華ICC智能物聯綜合管理平臺對技術組件進行模塊化和松耦合&#xff0c;將解決方案分層分級&#xff0c;提高面向智慧物聯的數據接入與生態合作能力。 0x02 漏洞概述 由于大華智能物聯綜合管理平臺使用了存在漏洞的Fastson組件,未經身份驗讓的攻擊者可利用 /e…

M功能-支付平臺(六)

target&#xff1a;離開柬埔寨倒計時-217day 今天突然發現我在csdn居然把我ip屬地搞出來了&#xff0c;之前都沒注意到&#xff0c;哎 前言 M功能演示版本做到后期(也就是第二周的后面3天)真的很心酸&#xff0c;這邊安排的4后端后面都放棄了&#xff0c;覺得做不出來&#…

ARM-V9 RME(Realm Management Extension)系統架構之系統能力的內存隔離和保護

安全之安全(security)博客目錄導讀 目錄 一、內存隔離和保護 1、顆粒PAS過濾Granular PAS filtering 2、Cache的一致性維護 2.1 物理別名點 Point of Physical Aliasing (PoPA) 2.2 加密點 3、內存(DRAM)保護 3.1 內存加密和完整性 3.2 DRAM scrubbing 本博客探討 RME…

網絡編程 —— Http使用httpClient實現頁面爬蟲

先去找類型的a標簽 取出圖片所在網址 取出https://desk.3gbizhi.com/deskMV/438.html 搭建Form界面 Http類 public static HttpClient Client { get; } static Http() {HttpClientHandler handler new HttpClientHandler();//處理消息對象//ServerCertificateCustomValidat…

安卓手機APP開發___設置鬧鐘

安卓手機APP開發___設置鬧鐘 目錄 概述 設置不精確鬧鐘 在特定時間后發出鬧鐘 在特定時間范圍內觸發鬧鐘 以大致有規律的時間間隔響起重復鬧鐘 設置精確的鬧鐘 系統會在未來的某個精確時刻調用精確鬧鐘。 可能不需要精確鬧鐘的用例 設置精確鬧鐘的方法 系統資源消耗…

萬億應急國債項目之通信指揮類應急裝備多鏈路聚合通信設備在應急行業中的重要作用

萬億應急國債項目的推出&#xff0c;無疑是我國在應急領域的一次重大舉措。在這一宏大藍圖中&#xff0c;通信指揮類應急裝備的多鏈路聚合通信設備顯得尤為重要&#xff0c;其在應急行業中所發揮的作用&#xff0c;堪稱不可或缺的關鍵一環。 通信指揮是應急響應中的核心環節&a…

QT C++ 讀寫mySQL數據庫 圖片 例子

在上篇文章中描述了怎樣搭建讀寫數據庫的環境。 本文更進一步&#xff0c;描述了讀寫mySQL數據庫&#xff0c;字符、整型數字、圖片。讀寫圖片相對難點。 數據庫的圖片字段用BLOB&#xff0c;如果圖片較大要用longblob,否則會報錯。 另外&#xff0c;讀寫數據庫都使用了短連…

Pytorch 星號*放在tensor前的作用

假如有一個多維tensor&#xff0c;名為id&#xff0c;那么*id的意思是什么呢&#xff1f; GPT答&#xff1a; 如果 id 是一個多維張量&#xff0c;那么 *id 在這種情況下會將這個多維張量解包成一個張量序列&#xff0c;其中每個元素都是一個更低維度的張量。具體來說&#x…

圖形學初識--空間變換

文章目錄 前言正文矩陣和向量相乘二維變換1、縮放2、旋轉3、平移4、齊次坐標下總結 三維變換1、縮放2、平移3、旋轉繞X軸旋轉&#xff1a;繞Z軸旋轉&#xff1a;繞Y軸旋轉&#xff1a; 結尾&#xff1a;喜歡的小伙伴可以點點關注贊哦 前言 前面章節補充了一下基本的線性代數中…

前端Vue小兔鮮兒電商項目實戰Day02

一、Pinia快速入門 此處見&#xff1a;Vue從入門到實戰Day12-CSDN博客 二、創建項目并精細化配置 1. 創建項目 2. src目錄調整 ①刪除一些初始化的默認文件 清空assets、components、store、views文件夾下的內容&#xff1b; ②修改剩余代碼內容 router/index.js import …

一個程序員的牢獄生涯(44)詢問

星期一 詢 問 在號子里開始了下午坐班的時候,過道內的大鐵柵欄被管教打開,我聽到開鎖的聲音后,心里變得激動起來。盼望著腳步聲能停在我們的號子門口,然后打開鐵門,喊一聲“眼鏡,出來!”。 通道內這次進來的是秦所,但他并沒有在我們號子門口停留,只是在走過的時候,低…

華為昇騰310 ATC模型轉換工具安裝

參考: https://bbs.huaweicloud.com/blogs/393282?utm_source=zhihu&utm_medium=bbs-ex&utm_campaign=other&utm_content=content https://www.hiascend.com/document/detail/zh/canncommercial/601/inferapplicationdev/atctool/atctool_0004.html 1、基本工具…

js知識點之閉包

閉包 什么是閉包 閉包&#xff0c;是 JavaScript 中一個非常重要的知識點&#xff0c;也是我們前端面試中較高幾率被問到的知識點之一。 打開《JavaScript 高級程序設計》和《 JavaScript 權威指南》&#xff0c;會發現里面針對閉包的解釋各執一詞&#xff0c;在網絡上搜索關…

Java中如何指定jdk的版本運行jar包

你的jdk安裝的目錄\bin\java -jar 你的jar包名字.jar 這是我的代碼示例 C:\Users\86177\.jdks\corretto-17.0.10\bin\java -jar big_event_study2-0.0.1- SNAPSHOT.jar

23種設計模式之一— — — —裝飾模式詳細介紹與講解

裝飾模式詳細講解 一、定義二、裝飾模式結構核心思想模式角色模式的UML類圖應用場景模式優點模式缺點 實例演示圖示代碼演示運行結果 一、定義 裝飾模式&#xff08;別名&#xff1a;包裝器&#xff09; 裝飾模式&#xff08;Decorator Pattern&#xff09;是結構型的設計模式…

LeetCode 每日一題 數學篇 2651.計算列車到站時間

給你一個正整數 arrivalTime 表示列車正點到站的時間&#xff08;單位&#xff1a;小時&#xff09;&#xff0c;另給你一個正整數 delayedTime 表示列車延誤的小時數。 返回列車實際到站的時間。 注意&#xff0c;該問題中的時間采用 24 小時制。 int findDelayedArrivalTi…

學業輔導導師:文心一言智能體詳細介紹和開發

一、前言 本期題目 開發方向&#xff1a;學習成長類 解讀&#xff1a; AI技術在學習成長方向的應用正日益增多&#xff0c;本期賽題需圍繞該方向開發智能體包括但不限于:作文輔導助手、個性化學習助手、考試助手、各垂類教育內容專家等 二、我的智能體&#xff1a;學業輔導…