C++入門之《拷貝構造函數》詳解

拷貝構造函數是構造函數的一個重載? ??

拷貝構造函數是特殊的構造函數,用于基于已存在對象創建新對象。比如定義一個?Person?類:

class Person {
private:std::string name;int age;
public:Person(const std::string& n, int a) : name(n), age(a) {}// 拷貝構造函數Person(const Person& other) : name(other.name), age(other.age) {}
};

這里?Person(const Person& other)?就是拷貝構造函數,它和普通構造函數?Person(const std::string& n, int a)?構成重載。

拷貝構造函數的參數要求

其第一個參數必須是類類型對象的引用。如上面?Person?類的拷貝構造函數?Person(const Person& other)other?就是對?Person?類型對象的引用。如果用值傳遞,編譯器報錯,因為值傳遞時為創建實參副本會調用拷貝構造函數,引發無窮遞歸調用。

以下解釋不使用值傳遞的原因

正常的拷貝構造函數使用場景

先看一個簡單的類示例,以?Person?類為例

#include <iostream>
#include <string>class Person {
private:std::string name;int age;
public:Person(const std::string& n, int a) : name(n), age(a) {}// 拷貝構造函數Person(const Person& other) : name(other.name), age(other.age) {std::cout << "拷貝構造函數被調用" << std::endl;}void display() {std::cout << "Name: " << name << ", Age: " << age << std::endl;}
};

在正常情況下,我們可以基于已有的?Person?對象通過拷貝構造函數來創建新對象,例如:

int main() {Person p1("Alice", 25);Person p2(p1);  // 這里調用拷貝構造函數,基于 p1 創建 p2p2.display();return 0;
}

上述代碼中,Person p2(p1);?語句調用了拷貝構造函數,將?p1?的數據成員值復制給?p2,程序能正常運行并輸出?Name: Alice, Age: 25,同時控制臺會輸出 “拷貝構造函數被調用”。

值傳遞引發的問題

當我們嘗試將?Person?對象作為函數參數以值傳遞的方式傳遞時,就會出現問題。看下面的代碼:

void printPerson(Person p) {p.display();
}int main() {Person p1("Bob", 30);printPerson(p1);  // 嘗試以值傳遞方式傳遞對象return 0;
}

在?printPerson(p1);?這行代碼中,由于是值傳遞,函數?printPerson?需要創建一個?Person?類型的形參?p?作為實參?p1?的副本。而創建這個副本的過程,就需要調用?Person?類的拷貝構造函數。

如果拷貝構造函數的參數也是以值傳遞的方式聲明,比如錯誤地寫成:

class Person {
private:std::string name;int age;
public:Person(const std::string& n, int a) : name(n), age(a) {}// 錯誤的拷貝構造函數聲明,參數為值傳遞Person(Person other) : name(other.name), age(other.age) {std::cout << "拷貝構造函數被調用" << std::endl;}void display() {std::cout << "Name: " << name << ", Age: " << age << std::endl;}
};

當執行?printPerson(p1);?時,為了創建?printPerson?函數的形參?p?作為?p1?的副本,需要調用拷貝構造函數。但由于拷貝構造函數的參數是值傳遞,又需要為這個參數創建實參的副本,這又會觸發拷貝構造函數的調用,如此循環往復,就形成了無窮遞歸調用

編譯器會檢測到這種潛在的無窮遞歸情況并報錯,因為這顯然是一個錯誤的邏輯,會導致程序棧溢出等嚴重問題。所以 C++ 規定拷貝構造函數的第一個參數必須是類類型對象的引用(一般是?const?引用,以避免在拷貝構造過程中意外修改原對象),以防止這種無窮遞歸調用的發生。

自定義類型對象拷貝行為

自定義類型傳值傳參和傳值返回會調用拷貝構造。例如:

Person createPerson() {Person p("Alice", 25);return p;
}

這里?createPerson?函數返回?Person?對象?p?時,會調用?Person?的拷貝構造函數創建返回值副本。

編譯器自動生成拷貝構造函數

若未顯式定義,編譯器會自動生成。比如:

class Point {
private:int x;int y;
};

編譯器自動生成的拷貝構造函數會對?x?和?y?進行值拷貝(淺拷貝),一個字節一個字節地拷貝。如果類包含自定義類型成員變量,會調用該成員變量所屬類的拷貝構造函數。

不同情況是否需顯式實現拷貝構造函數

  • 不需要顯式實現的情況:像只含內置類型且無指向資源成員變量的?Date?類,編譯器自動生成的拷貝構造函數能滿足需求,無需顯式實現。
  • 需要顯式實現的情況:以?Stack?類為例,若類中有指針成員變量(如?_a?指向資源),編譯器自動生成的淺拷貝可能導致問題(如兩個對象的指針指向同一塊內存,釋放時出錯),需實現深拷貝,即自己實現拷貝構造函數,對指向的資源也進行拷貝。
  • 特殊情況:對于?MyQueue?類,內部主要是自定義類型?Stack?成員,編譯器自動生成的拷貝構造函數會調用?Stack?的拷貝構造函數,一般無需顯式實現?MyQueue?的拷貝構造函數。若一個類顯式實現了析構函數釋放資源,通常也需顯式寫拷貝構造函數,避免資源管理問題。

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

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

相關文章

Ollama命令使用指南

Ollama 命令使用指南 Ollama 命令使用指南1. Ollama 命令概覽2. Ollama 命令詳解2.1 啟動 Ollama2.2 創建模型2.3 查看模型信息2.4 運行模型2.5 停止運行的模型2.6 從注冊表拉取模型2.7 推送模型到注冊表2.8 列出本地模型2.9 查看正在運行的模型2.10 復制模型2.11 刪除模型 3. …

為什么配置Redis時候要序列化配置呢

序列化和反序列化&#xff1f;&#xff1a; 序列化&#xff1a;將對象轉換為二進制數據&#xff0c;以便存儲到Redis中。 反序列化&#xff1a;將Redis中的二進制數據轉換回對象&#xff0c;以便在應用程序中使用。 1. 默認序列化器的問題 如果不配置序列化器&#xff0c;Re…

【問】強學如何支持 遷移學習呢?

案例&#xff1a;從CartPole-v1遷移到MountainCar-v0 在源環境&#xff08;CartPole-v1&#xff09;中訓練模型 首先&#xff0c;我們使用DQN算法在CartPole-v1環境中訓練一個強化學習模型。以下是代碼示例&#xff1a; import gym import torch import torch.nn as nn impor…

深入淺出Java反射:掌握動態編程的藝術

小程一言反射何為反射反射核心類反射的基本使用獲取Class對象創建對象調用方法訪問字段 示例程序應用場景優缺點分析優點缺點 注意 再深入一些反射與泛型反射與注解反射與動態代理反射與類加載器 結語 小程一言 本專欄是對Java知識點的總結。在學習Java的過程中&#xff0c;學習…

【算法與數據結構】并查集詳解+題目

目錄 一&#xff0c;什么是并查集 二&#xff0c;并查集的結構 三&#xff0c;并查集的代碼實現 1&#xff0c;并查集的大致結構和初始化 2&#xff0c;find操作 3&#xff0c;Union操作 4&#xff0c;優化 小結&#xff1a; 四&#xff0c;并查集的應用場景 省份…

C語言簡單練習題

文章目錄 練習題一、計算n的階乘bool類型 二、計算1!2!3!...10!三、計算數組arr中的元素個數二分法查找 四、動態打印字符Sleep()ms延時函數system("cls")清屏函數 五、模擬用戶登錄strcmp()函數 六、猜數字小游戲產生一個隨機數randsrandRAND_MAX時間戳time() 示例 …

ShenNiusModularity項目源碼學習(8:數據庫操作)

ShenNiusModularity項目使用SqlSugar操作數據庫。在ShenNius.Repository項目中定義了ServiceCollectionExtensions.AddSqlsugarSetup函數注冊SqlSugar服務&#xff0c;并在ShenNius.Admin.API項目的ShenniusAdminApiModule.OnConfigureServices函數中調用&#xff0c;SqlSugar所…

MATLAB圖像處理:圖像特征概念及提取方法HOG、SIFT

圖像特征是計算機視覺中用于描述圖像內容的關鍵信息&#xff0c;其提取質量直接影響后續的目標檢測、分類和匹配等任務性能。本文將系統解析 全局與局部特征的核心概念&#xff0c;深入講解 HOG&#xff08;方向梯度直方圖&#xff09;與SIFT&#xff08;尺度不變特征變換&…

java枚舉類型的查找

AllArgsConstructor Getter public enum FileFilterRangeEnum {FILE_NAME("文件名稱","fileName"),FILE_CONTENT("文件內容","fileContent");private final String text;private final String value;// 根據傳入的字符串值查找對應的枚…

小白win10安裝并配置yt-dlp

需要yt-dlp和ffmpeg 注意存放路徑最好都是全英文 win10安裝并配置yt-dlp 一、下載1.下載yt-dlp2. fffmpeg下載 二、配置環境三、cmd操作四、yt-dlp下視頻操作 一、下載 1.下載yt-dlp yt-dlp地址 找到win的壓縮包點下載&#xff0c;并解壓 2. fffmpeg下載 ffmpeg官方下載 …

【技術解析】MultiPatchFormer:多尺度時間序列預測的全新突破

今天給我大家帶來一篇最新的時間序列預測論文——MultiPatchFormer。這篇論文提出了一種基于Transformer的創新模型&#xff0c;旨在解決時間序列預測中的關鍵挑戰&#xff0c;特別是在處理多尺度時間依賴性和復雜通道間相關性時的難題。MultiPatchFormer通過引入一維卷積技術&…

145,【5】 buuctf web [GWCTF 2019]mypassword

進入靶場 修改了url后才到了注冊頁面 注測后再登錄 查看源碼 都點進去看看 有個反饋頁面 再查看源碼 又有收獲 // 檢查$feedback是否為數組 if (is_array($feedback)) {// 如果是數組&#xff0c;彈出提示框提示反饋不合法echo "<script>alert(反饋不合法);<…

CTF-WEB: 利用iframe標簽利用xss,waf過濾后再轉換漏洞-- N1ctf Junior display

核心邏輯 // 獲取 URL 查詢參數的值 function getQueryParam(param) { // 使用 URLSearchParams 從 URL 查詢字符串中提取參數 const urlParams new URLSearchParams(window.location.search); // 返回查詢參數的值 return urlParams.get(param); } // 使用 DOMPuri…

晶閘管主要參數分析與損耗計算

1. 主要參數 斷態正向可重復峰值電壓 :是晶閘管在不損壞的情況下能夠承受的正向最大阻斷電壓。斷態正向不可重復峰值電壓 :是晶閘管只有一次可以超過的正向最大阻斷電壓,一旦晶閘管超過此值就會損壞,一般情況下 反向可重復峰值電壓 :是指晶閘管在不損壞的情況下能夠承受的…

el-select 設置寬度 沒效果

想實現下面的效果&#xff0c;一行兩個&#xff0c;充滿el-col12 然后設置了 width100%,當時一直沒有效果 解決原因&#xff1a; el-form 添加了 inline 所以刪除inline屬性 即可

Python創建FastApi項目模板

1. 項目結構規范 myproject/ ├── app/ │ ├── core/ # 核心配置 │ │ ├── config.py # 環境配置 │ │ └── security.py # 安全配置 │ ├── routers/ # 路由模塊 │ │ └── users.py # 用戶路由 │ ├…

面試完整回答:SQL 分頁查詢中 limit 500000,10和 limit 10 速度一樣快嗎?

首先&#xff1a;在 SQL 分頁查詢中&#xff0c;LIMIT 500000, 10 和 LIMIT 10 的速度不會一樣快&#xff0c;以下是原因和優化建議&#xff1a; 性能差異的原因 LIMIT 10&#xff1a; 只需要掃描前 10 條記錄&#xff0c;然后返回結果。 性能非常高&#xff0c;因為數據庫只…

一款利器提升 StarRocks 表結構設計效率

CloudDM 個人版是一款數據庫數據管理客戶端工具&#xff0c;支持 StarRocks 可視化建表&#xff0c;創建表時可選擇分桶、配置數據模型。目前版本持續更新&#xff0c;在修改 StarRocks 表結構方面進一步優化&#xff0c;大幅提升 StarRocks 表結構設計效率。當前 CloudDM 個人…

數量5 - 平面圖形、立體幾何

目錄 一、平面幾何問題1.三角形2.其他圖形二、立體幾何與特殊幾何1.表面積2.體積3.等比放縮(簡單)4.幾何最值(簡單)5.最短路徑一、平面幾何問題 平面圖形: 立體圖形: 1.三角形 特殊直角

CAS單點登錄(第7版)7.授權

如有疑問&#xff0c;請看視頻&#xff1a;CAS單點登錄&#xff08;第7版&#xff09; 授權 概述 授權和訪問管理 可以使用以下策略實施授權策略以保護 CAS 中的應用程序和依賴方。 服務訪問策略 服務訪問策略允許您定義授權和訪問策略&#xff0c;以控制對向 CAS 注冊的…