C++默認構造函數被隱式刪除

一、

看cppreference時,發現被隱式刪除的構造函數,查詢做如下記錄:

struct F
{int& ref; // reference memberconst int c; // const member// F::F() is implicitly defined as deleted
};// user declared copy constructor (either user-provided, deleted or defaulted)
// prevents the implicit generation of a default constructor

在 C++ 中,struct F的默認構造函數F::F()被隱式刪除,主要與類中包含的引用成員const 成員有關。以下是具體原因及底層機制的詳細解析:

1. 引用成員(int& ref)的影響

  • 引用的特性:引用必須在初始化時綁定到一個已存在的對象,且無法重新綁定。
  • 默認構造函數的行為:默認構造函數不會為成員變量提供任何初始化值。當類中存在引用成員時,默認構造函數無法滿足引用的初始化要求,因此會被隱式刪除。
struct A {int& ref; // 引用成員
};A a; // 錯誤:無法默認構造A,因為ref未初始化

2. const 成員(const int c)的影響

  • const 的特性:const 成員必須在構造時初始化,且之后無法修改。
  • 默認構造函數的限制:默認構造函數不會為 const 成員賦初值,導致 const 成員未初始化,因此默認構造函數被隱式刪除。
struct B {const int c; // const成員
};B b; // 錯誤:無法默認構造B,因為c未初始化

3. 兩者共同作用的結果

當類同時包含引用成員const 成員時,默認構造函數需要同時滿足兩者的初始化要求,但默認構造函數無法提供任何初始化邏輯,因此會被編譯器隱式刪除。

struct F {int& ref;    // 引用必須初始化const int c; // const必須初始化
};// 等價于:
struct F {int& ref;const int c;F() = delete; // 編譯器隱式添加
};

4. 如何正確構造此類?

必須顯式定義構造函數,為引用成員和 const 成員提供初始化:

struct F {int& ref;const int c;// 顯式構造函數,必須初始化所有成員F(int& r, int val) : ref(r), c(val) {}
};int main() {int x = 10;F f(x, 42); // 正確:引用綁定到x,const成員初始化為42
}

5. 其他導致默認構造函數被刪除的場景

除了引用和 const 成員外,以下情況也會導致默認構造函數被隱式刪除:

  • 包含未默認構造的成員(如自定義類型且無默認構造函數):
    struct G {std::string str; // std::string有默認構造函數,允許默認構造
    };struct H {G g;         // G有默認構造函數,H的默認構造函數有效std::mutex m; // std::mutex無默認構造函數,H的默認構造函數被刪除
    };
    
  • 基類或成員的默認構造函數被刪除:
    struct Base {Base() = delete; // 顯式刪除默認構造函數
    };struct Derived : Base {// Derived的默認構造函數被隱式刪除,因為Base無法默認構造
    };
    

總結

struct F的默認構造函數被隱式刪除的核心原因是:

  • 引用成員ref必須在構造時綁定到有效對象;
  • const 成員c必須在構造時初始化;
    而默認構造函數無法滿足上述要求,因此編譯器自動將其標記為delete。若要使用此類,必須顯式定義構造函數以完成成員初始化。

二、

struct G
{G(const G&) {}// G::G() is implicitly defined as deleted
};struct H
{H(const H&) = delete;// H::H() is implicitly defined as deleted
};struct I
{I(const I&) = default;// I::I() is implicitly defined as deleted
};

這些結構體的默認構造函數被刪除的原因各不相同,涉及 C++ 的特殊成員函數生成規則。下面逐一分析:

1.?struct G

struct G {G(const G&) {}  // 顯式定義拷貝構造函數// G::G() 被隱式刪除
};

原因

  • 拷貝構造函數的影響:當顯式定義了拷貝構造函數(無論是否為默認default或刪除delete),編譯器不會自動生成默認構造函數
  • 用戶責任:若需要默認構造,必須手動定義:
    G() = default;  // 顯式保留默認構造
    

2.?struct H

struct H {H(const H&) = delete;  // 顯式刪除拷貝構造函數// H::H() 被隱式刪除
};

原因

  • 拷貝構造函數的刪除不直接影響默認構造:刪除拷貝構造函數本身不會導致默認構造函數被刪除
  • 潛在依賴:若H的成員或基類需要拷貝構造(例如std::unique_ptr),編譯器可能因無法生成拷貝構造而隱式刪除默認構造。但僅從代碼看,這一規則不適用,因此H的默認構造函數不應該被刪除
  • 結論:題目中的注釋可能有誤,H::H()?通常不會被隱式刪除,除非存在其他依賴。

3.?struct I

struct I {I(const I&) = default;  // 顯式默認拷貝構造函數// I::I() 被隱式刪除
};

原因

  • G相同的規則:顯式默認=default拷貝構造函數,仍屬于顯式定義拷貝構造函數,因此編譯器不會自動生成默認構造函數
  • 例外情況:若I包含引用成員const 成員,即使不定義拷貝構造函數,默認構造函數也會被刪除(見前一個問題的解釋)。但題目中未提及這些成員,因此主要原因仍是顯式定義拷貝構造函數

總結

結構體默認構造函數被刪除的原因
G顯式定義拷貝構造函數,編譯器不生成默認構造。
H注釋可能有誤,刪除拷貝構造函數本身不影響默認構造。
I顯式默認拷貝構造函數,編譯器不生成默認構造。

C++ 特殊成員函數生成規則

  • 默認構造函數:當且僅當沒有顯式定義任何構造函數時,編譯器自動生成。
  • 拷貝構造函數:當且僅當沒有顯式定義拷貝 / 移動構造函數時,編譯器自動生成。
  • 拷貝賦值運算符:當且僅當沒有顯式定義拷貝 / 移動賦值運算符時,編譯器自動生成。

現代 C++ 建議
若需要默認構造函數,顯式聲明:

MyClass() = default;  // 顯式保留默認行為

若不需要默認構造,顯式刪除:

MyClass() = delete;  // 禁止默認構造

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

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

相關文章

6.ref創建對象類型的響應式數據

其實ref接收的數據可以是&#xff1a;基本類型、對象類型。若ref接收的是對象類型&#xff0c;內部其實也是調用了reactive函數。 <template><div class"person"><h2>汽車信息&#xff1a;一臺{{ car.brand }}汽車&#xff0c;價值{{ car.price }…

如何設計一個用于大規模生產任務的人工智能AI系統

部署一個SOTA模型&#xff0c;讓它服務數百萬用戶&#xff0c;處理TB級別的數據&#xff0c;并且7x24小時可靠運行是件非常有挑戰性的工作。我們將探討構建一個能夠創建LLM、多模態模型以及各種其他AI產品的大規模AI系統所需的每個開發階段。每個開發階段如何相互關聯&#xff…

國債與企業債:穩健與高收益的債券選擇

債券市場是投資者獲取穩定收益的重要渠道&#xff0c;而國債和企業債是最常見的兩種債券類型。它們雖然都屬于固定收益類產品&#xff0c;但在風險、收益和適用人群上有顯著區別。 1. 概念對比&#xff1a;國家信用 vs. 企業信用 &#xff08;1&#xff09;國債&#xff08;政…

MySQL提升

事務 事務&#xff1a;在多個操作合在一起視為一個整體。要么就不做、要么就做完。 事務應該滿足ACID A : 原子性。不可分割。C : 一致性。追求的目標&#xff0c;在開始到結束沒有發生預定外的情況。I : 隔離性。不同的事務是獨立的。D : 持久性。系統崩潰&#xff0c;數據依然…

MySQL用戶和授權

開放MySQL白名單 可以通過iptables-save命令確認對應客戶端ip是否可以訪問MySQL服務&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…

基礎篇:4. 頁面渲染流程與性能優化

頁面渲染流程與性能優化詳解&#xff08;完整版&#xff09; 一、現代瀏覽器渲染流程&#xff08;詳細說明&#xff09; 1. 構建DOM樹 瀏覽器接收到HTML文檔后&#xff0c;會逐步解析并構建DOM&#xff08;Document Object Model&#xff09;樹。具體過程如下&#xff1a; (…

vue3 vite.config.js 引入bem.scss文件報錯

[sass] Can’t find stylesheet to import. ? 1 │ use “/bem.scss” as *; │ ^^^^^^^^^^^^^^^^^^^^^^ ? src\App.vue 1:1 root stylesheet 分析 我們遇到了一個在Vue3項目中使用Vite時&#xff0c;在vite.config.js中引入bem.scss文件報錯的問題。錯誤信息指出在App.vue…

python打卡第50天

知識點回顧&#xff1a; resnet結構解析CBAM放置位置的思考針對預訓練模型的訓練策略 差異化學習率三階段微調 現在我們思考下&#xff0c;是否可以對于預訓練模型增加模塊來優化其效果&#xff0c;這里我們會遇到一個問題 預訓練模型的結構和權重是固定的&#xff0c;如果修…

MySQL 并發控制和日志

MySQL 是一個廣泛使用的關系數據庫管理系統&#xff0c;在高并發環境中&#xff0c;如何有效地控制并發和管理日志至關重要。本文將詳細介紹 MySQL 的并發控制機制和日志管理策略&#xff0c;以幫助開發人員和數據庫管理員更好地理解和優化數據庫性能。 一、并發控制 并發控制…

創意意境古風唯美中國風PPT模版分享

故宮文化經典傳統PPT模版&#xff0c;創意中國風PPT模版&#xff0c;朱紅簡約新國風PPT模版&#xff0c;意境中國風PPT模版&#xff0c;最愛中國風PPT模版&#xff0c;意境古風唯美商業計劃書PPT模版 創意意境古風唯美中國風PPT模版分享&#xff1a;古風中國風PTP模版分享https…

系統網站首頁三種常見布局vue+elementui

左中右菜單布局 <template><el-container><el-menu class"el-menu-vertical-demo" style"width: 80px; height: 100vh;"background-color"#545c64"text-color"#fff"active-text-color"#ffd04b"select"…

復習Git命令、Git命令使用流程、VSCode+Git插件管理工程源碼

目錄 1 引言 2 直接整理一個常用的流程&#xff0c;而不是死記硬背各種命令 3 解決沖突的說明和理解 4 git fetch的說明和理解 5 真正開發不用Git命令&#xff0c;而是使用VSCode插件管理工程 1 引言 以前主要用svn&#xff0c;Git用的少&#xff0c;這次再復習一下Git命…

384_C++_unit是4字節大小,能存儲32位(bit)bool操作,[7][48]這里用于計劃表的時間節點內,二維數組中每一位代表一種AI功能的開關狀態

前置了解 uint 并不是 C/C++ 標準中的 原生類型,但不同平臺或框架可能有定義。通常: 1. uint 可能是 unsigned int 的別名 在某些代碼庫(如 Arduino、某些嵌入式系統、部分庫的頭文件)中,uint 可能被定義為:typedef unsigned int uint;此時,uint 的大小和 unsigned in…

css~word-break屬性

CSS中如何強制換行“....................................”&#xff1f; 當盒子寬度能放下“...”元素時&#xff0c;正常展示如下&#xff1a; 當盒子寬度不夠放“...”元素時&#xff0c;文本就會溢出&#xff0c;導致整個內容被截斷&#xff1a; 如何才能讓其正常展示而不…

【Algorithm】Union-Find簡單介紹

文章目錄 Union-Find1 基本概念1.1 Find(x) - 查詢操作1.2 Union(x, y) - 合并操作 2 并查集的結構和優化2.1 數據結構設計2.2 兩大優化策略&#xff08;關鍵&#xff09;2.2.1 路徑壓縮&#xff08;Path Compression&#xff09;2.2.2 按秩合并&#xff08;Union by Rank or S…

LeetCode 高頻 SQL 50 題(基礎版)之 【高級字符串函數 / 正則表達式 / 子句】· 上

題目&#xff1a;1667. 修復表中的名字 題解&#xff1a; select user_id, concat(upper(left(name,1)),lower(right(name,length(name)-1))) name from Users order by user_id題目&#xff1a;1527. 患某種疾病的患者 題解&#xff1a; select * from Patients where con…

Linux系統的CentOS7發行版安裝MySQL80

文章目錄 前言Linux命令行內的”應用商店”安裝CentOS的安裝軟件的yum命令安裝MySQL1. 配置yum倉庫2. 使用yum安裝MySQL3. 安裝完成后&#xff0c;啟動MySQL并配置開機自啟動4. 檢查MySQL的運行狀態 MySQL的配置1. 獲取MySQL的初始密碼2. 登錄MySQL數據庫系統3. 修改root密碼4.…

Java + Spring Boot項目枚舉(Enum)目錄建議

在Java Spring Boot項目中&#xff0c;枚舉&#xff08;Enum&#xff09;的定義文件沒有固定的強制目錄&#xff0c;但通常遵循項目結構和最佳實踐來組織代碼。以下是常見的推薦位置&#xff1a; 1. 領域模型相關枚舉 目錄: domain/enums 或 model/enums 場景: 當枚舉與業務模…

Vue 模板語句的數據來源

&#x1f9e9; Vue 模板語句的數據來源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表達式、指令綁定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一個特定的作用域內求值。這個作用域由當前 組件…

全新AI驅動Workspace Security 套件發布!Fortinet 電子郵件安全產品矩陣升級

專注推動網絡與安全融合的全球性綜合網絡安全解決方案供應商 Fortinet&#xff08;NASDAQ&#xff1a;FTNT&#xff09;&#xff0c;近日宣布發布新一代企業級郵件安全解決方案FortiMail Workspace Security 安全套件&#xff0c;全面增強旗下數據和生產力安全產品組合&#xf…