C++的前世今生-C++11

C++98(ISO/IEC 14882:1998)

C++98 是 C++ 的第一個標準化版本(ISO/IEC 14882:1998),它正式確立了 C++ 的核心語言特性和標準庫。以下是 C++98 的主要特性總結:

一、核心語言特性**

  1. 模板(Templates)
    • 支持函數模板和類模板,實現泛型編程。
    • 例如:std::vectorstd::sort 等標準庫組件依賴模板。
  2. 標準模板庫(STL)
    • 包含容器(如 vectorlistmap)、迭代器(iterators)和算法(如 sortfind)。
    • 基于泛型編程思想,強調“數據與算法分離”。
  3. 異常處理(Exception Handling)
    • 引入 trycatchthrow 機制,支持錯誤處理的標準化。
  4. 命名空間(Namespaces)
    • 避免命名沖突,例如 std 是標準庫的命名空間。
  5. RTTI(運行時類型識別)
    • 支持 typeiddynamic_cast,允許在運行時檢查類型。
  6. bool 類型
    • 引入 bool 關鍵字(true/false),取代傳統的 int 表示布爾值。
  7. mutable 關鍵字
    • 允許在 const 成員函數中修改被標記為 mutable 的成員變量。
  8. 顯式類型轉換
    • 提供 static_castdynamic_castconst_castreinterpret_cast,替代 C 風格的強制轉換。
  9. 默認參數和函數重載
    • 支持函數參數的默認值和函數重載(相同函數名,不同參數列表)。

二、標準庫組件

  1. 容器(Containers)
    • 序列容器:vectordequelist
    • 關聯容器:setmapmultisetmultimap
    • 適配器:stackqueuepriority_queue
  2. 迭代器(Iterators)
    • 提供統一的遍歷容器元素的接口(如 begin()end())。
  3. 算法(Algorithms)
    • sort()find()copy() 等,通過迭代器操作容器。
  4. 字符串類(std::string)
    • 提供安全的字符串操作,替代 C 風格字符數組。
  5. 輸入/輸出流(I/O Streams)
    • iostream(如 cincout)、fstream(文件操作)、sstream(字符串流)。
  6. 數值處理
    • 定義數值類型的極值, 提供數學函數。

三、其他重要特性

  1. 局部對象析構順序
    • 局部對象的析構順序與構造順序相反(RAII 基礎)。
  2. 運算符重載
    • 允許自定義運算符行為(如 +<<)。
  3. 友元(friend)
    • 允許非成員函數或類訪問私有成員。
  4. 靜態成員
    • 類的靜態成員變量和函數。

C++03(ISO/IEC 14882:2003)

C++03(ISO/IEC 14882:2003)是 C++98 的一個技術修正版本(Technical Corrigendum),主要修復了標準中的缺陷和模糊表述,并未引入顯著的新特性。它通常被視為 C++98 的“bug fix”版本,核心特性和語法與 C++98 完全一致。以下是 C++03 的細節說明:

一、C++03 的核心變化

  1. 標準文本修正
    • 修復了 C++98 標準中的語法歧義未定義行為的表述。
    • 例如:模板解析規則、模板友元聲明的語法等細節更明確。
  2. 標準庫的兼容性改進
    • 修正了 STL 中部分容器的接口行為(如 std::vector 的成員函數異常安全性)。
    • 明確 std::basic_string 的存儲連續性(C++03 保證 &s[0] 是連續內存)。
  3. 數值限制的擴展
    • 在 `` 中增加了對 long longunsigned long long 的支持(盡管這些類型在 C++11 才正式成為關鍵字)。

二、與 C++98 的兼容性

  • 語法完全兼容:所有 C++98 代碼在 C++03 中無需修改即可編譯。
  • 編譯器支持:主流編譯器(如 GCC、MSVC)通常將 C++98 和 C++03 視為同一版本實現。

三、為什么需要 C++03?

C++98 標準中存在一些未明確的邊界情況,例如:

  • 模板中嵌套依賴名稱的解析規則(需用 typename 消除歧義)。
  • 局部模板特化的合法性(C++03 明確禁止)。
    這些修正提高了代碼的可移植性和一致性。

C++11(ISO/IEC 14882:2011)

C++11(ISO/IEC 14882:2011)是 C++ 的一次重大更新,引入了許多革命性特性,顯著提升了代碼的簡潔性、安全性和性能。以下是 C++11 的核心特性分類總結:

一、核心語言特性

  1. 自動類型推導(auto

    • 編譯器自動推斷變量類型,簡化代碼:

      auto x = 5;          // int
      auto str = "hello";  // const char*
      
  2. 范圍 for 循環

    • 簡化容器遍歷:

      std::vector<int> v = {1, 2, 3};
      for (auto& num : v) { std::cout << num; }
      
  3. 右值引用與移動語義(&&

    • 避免深拷貝,提升性能:

      std::vector<std::string> v;
      v.push_back(std::move(str));  // 移動而非拷貝
      
  4. Lambda 表達式

    • 匿名函數,支持閉包:

      auto add = [](int a, int b) { return a + b; };
      std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
      
  5. nullptr 關鍵字

    • 替代NULL,明確表示空指針:

      int* p = nullptr;
      
  6. 強類型枚舉(enum class

    • 避免命名沖突,限制作用域:

      enum class Color { Red, Green };
      Color c = Color::Red;  // 必須帶作用域
      
  7. constexpr 常量表達式

    • 編譯時計算:

      constexpr int square(int x) { return x * x; }
      int arr[square(3)];  // 編譯期確定數組大小
      
  8. 委托構造函數

    • 構造函數調用其他構造函數:

      class A {
      public:A() : A(0) {}      // 委托給 A(int)A(int x) { /*...*/ }
      };
      
  9. overridefinal

    • 顯式標記虛函數重寫或禁止繼承:

      class B final {};       // 禁止繼承
      virtual void foo() override;  // 確保重寫基類虛函數
      

二、標準庫增強

  1. 智能指針

    • 自動內存管理:

      std::unique_ptr<int> ptr(new int(10));  // 獨占所有權
      std::shared_ptr<int> sptr = std::make_shared<int>(20);  // 共享所有權
      
  2. std::thread 多線程支持

    • 原生多線程庫:

      std::thread t([]() { std::cout << "Hello from thread!"; });
      t.join();
      
  3. 哈希表容器

    • 新增無序關聯容器:

      std::unordered_map<std::string, int> hash_map;
      
  4. std::functionstd::bind

    • 通用函數包裝器:

      std::function<int(int, int)> func = std::plus<int>();
      std::bind(func, 1, std::placeholders::_1)(2);  // 綁定參數
      
  5. 正則表達式(``)

    • 支持正則操作:

      std::regex pattern("\\d+");
      bool match = std::regex_search("123", pattern);
      
  6. 元組(std::tuple

    • 多類型值集合:

      auto t = std::make_tuple(1, "hello", 3.14);
      

三、其他重要特性

  1. 變長模板(Variadic Templates)

    • 支持任意數量模板參數:

      template<typename... Args>
      void log(Args... args) { /*...*/ }
      
  2. 列表初始化(Uniform Initialization)

    • 統一初始化語法:

      std::vector<int> v{1, 2, 3};  // 替代舊式括號初始化
      
  3. static_assert 編譯時斷言

    • 編譯期條件檢查:

      static_assert(sizeof(int) == 4, "int must be 4 bytes");
      
  4. noexcept 異常規范

    • 標記函數不拋異常:

      void foo() noexcept { /*...*/ }
      

C++14(ISO/IEC 14882:2014)

C++14(ISO/IEC 14882:2014)是 C++11 的小幅改進版本,主要目標是完善 C++11 的特性并修復一些缺陷,而非引入重大變革。以下是 C++14 的核心特性分類總結:

一、核心語言改進

  1. 泛型 Lambda 表達式

    • Lambda 參數支持auto,實現真正的泛型:

      auto lambda = [](auto x, auto y) { return x + y; };
      std::cout << lambda(1, 2.5);  // 混合類型參數
      
  2. constexpr 函數擴展

    • 允許constexpr函數包含局部變量、循環和簡單分支:

      constexpr int factorial(int n) {int result = 1;for (int i = 1; i <= n; ++i) result *= i;return result;
      }
      int arr[factorial(5)];  // 編譯期計算 120
      
  3. 變量模板(Variable Templates)

    • 模板可以定義變量而不僅是類型或函數:

      template<typename T>
      constexpr T pi = T(3.1415926535897932385);
      std::cout << pi<double>;  // 輸出 double 精度的 π
      
  4. 二進制字面量

    • 直接使用二進制數:

      int mask = 0b110101;  // 十進制 53
      
  5. 數字分隔符(Digit Separators)

    • 提高長數字可讀性:

      int million = 1'000'000;
      double pi = 3.141'592'6535;
      
  6. 函數返回類型推導(auto 返回類型)

    • 省略尾置返回類型(C++11 需要-> decltype(...)):

      auto add(int a, int b) { return a + b; }  // 自動推導為 int
      
  7. [[deprecated]] 屬性

    • 標記過時代碼,編譯時警告:

      [[deprecated("Use new_func() instead")]]
      void old_func() {}
      

二、標準庫增強

  1. std::make_unique

    • 補充 C++11 的std::make_shared,為unique_ptr 提供工廠函數:

      auto ptr = std::make_unique<int>(42);  // 替代 new
      
  2. 標準庫的 constexpr 支持

    • 部分標準庫函數(如 std::arraystd::tuple 的部分操作)可在編譯期使用。
  3. std::integer_sequence

    • 編譯時整數序列,用于元編程:

      template<typename T, T... Ints>
      void print_sequence(std::integer_sequence<T, Ints...>) {((std::cout << Ints << ' '), ...);  // C++17 折疊表達式
      }
      print_sequence(std::index_sequence<1, 2, 3>{});  // 輸出: 1 2 3
      
  4. std::exchange

    • 原子性地替換對象值并返回舊值:

      int x = 1;
      int old = std::exchange(x, 42);  // x=42, old=1
      
  5. std::quoted

    • 方便處理帶引號的字符串(如 CSV 文件):

      std::cout << std::quoted("Hello");  // 輸出: "Hello"
      

三、其他改進

  1. 聚合成員初始化擴展

    • 允許聚合類(無自定義構造函數的類)使用默認初始化:

      struct Point { int x; int y; };
      Point p{1};  // y 初始化為 0(C++11 需完整初始化)
      
  2. Lambda 捕獲表達式的改進

    • 支持在捕獲列表中直接初始化變量:

      auto lambda = [value = 42]() { return value; };
      
  3. sizeof 運算符的擴展

    • 可直接用于成員變量(無需實例化對象):

      struct S { int x; double y; };
      size_t sz = sizeof(S::x);  // 等價于 sizeof(int)
      

C++17(ISO/IEC 14882:2020)

C++17(ISO/IEC 14882:2017)是 C++14 的增量升級版本,雖然沒有 C++11 或 C++20 那樣的革命性變化,但引入了許多實用特性,進一步簡化代碼并提升性能。以下是 C++17 的核心特性分類總結:

一、核心語言特性

  1. 結構化綁定(Structured Bindings)

    • 解構元組、結構體或數組為獨立變量:

      std::pair<int, std::string> p{42, "hello"};
      auto [num, str] = p;  // num=42, str="hello"
      
  2. ifswitch 的初始化語句

    • 在條件語句中定義局部變量:

      if (auto it = map.find(key); it != map.end()) {// 使用 it
      }  // it 作用域僅限于 if 塊
      
  3. constexpr if

    • 編譯期條件分支,簡化模板元編程:

      template <typename T>
      auto get_value(T t) {if constexpr (std::is_pointer_v<T>) return *t;else return t;
      }
      
  4. 內聯變量(Inline Variables)

    • 允許頭文件中定義inline變量,避免多重定義錯誤:

      // header.h
      inline int global_value = 42;  // 多個 cpp 包含時不會鏈接錯誤
      
  5. 折疊表達式(Fold Expressions)

    • 簡化可變參數模板的展開:

      template <typename... Args>
      auto sum(Args... args) { return (... + args); }  // args1 + args2 + ...
      
  6. auto 模板參數

    • 非類型模板參數支持auto

      template <auto value>
      void print() { std::cout << value; }
      print<42>();  // 輸出 42
      
  7. std::byte

    • 明確表示字節的類型(替代charunsigned char):

      std::byte b{0xFF};
      
  8. 構造函數模板推導(CTAD)

    • 省略模板參數,自動推導容器類型:

      std::pair p(1, "hello");  // 自動推導為 std::pair<int, const char*>
      std::vector v{1, 2, 3};   // 推導為 std::vector<int>
      

二、標準庫增強

  1. std::optional

    • 表示可選值,避免使用nullptr或特殊值:

      std::optional<int> maybe_num = std::nullopt;
      if (maybe_num) std::cout << *maybe_num;
      
  2. std::variant

    • 類型安全的聯合體(替代union):

      std::variant<int, std::string> v = "hello";
      std::cout << std::get<std::string>(v);  // 輸出 hello
      
  3. std::any

    • 存儲任意類型:

      std::any a = 42;
      std::cout << std::any_cast<int>(a);  // 輸出 42
      
  4. std::string_view

    • 非擁有的字符串視圖,避免拷貝:

      std::string s = "hello";
      std::string_view sv = s.substr(0, 3);  // "hel"(不拷貝數據)
      
  5. std::filesystem

    • 文件系統操作(跨平臺路徑處理):

      namespace fs = std::filesystem;
      fs::path p = "dir/file.txt";
      if (fs::exists(p)) std::cout << p.filename();  // "file.txt"
      
  6. 并行算法(Parallel Algorithms)

    • 標準庫算法支持并行執行:

      std::vector<int> v = {...};
      std::sort(std::execution::par, v.begin(), v.end());  // 并行排序
      
  7. std::invokestd::apply

    • 統一調用函數和展開元組參數:

      auto func = [](int a, int b) { return a + b; };
      std::tuple args{1, 2};
      std::cout << std::apply(func, args);  // 輸出 3
      

三、其他改進

  1. 嵌套命名空間定義簡化

    • 簡化嵌套命名空間的語法:

      namespace A::B::C { }  // 替代 namespace A { namespace B { namespace C {} } }
      
  2. __has_include 預處理表達式

    • 檢測頭文件是否可用:

      #if __has_include(<optional>)#include <optional>
      #endif
      
  3. [[fallthrough]] 屬性

    • 明確標記switch中的穿透(fallthrough)行為:

      switch (x) {case 1: do_something(); [[fallthrough]];  // 明確告知編譯器case 2: break;
      }
      
  4. [[nodiscard]] 屬性

    • 強制檢查函數返回值(避免忽略錯誤):

      [[nodiscard]] int compute_important_value();
      compute_important_value();  // 編譯器警告:未使用返回值
      

C++20(ISO/IEC 14882:2020)**

C++20(ISO/IEC 14882:2020)是繼 C++17 之后的重大更新,引入了許多革命性特性,顯著提升了代碼的表達能力、性能和安全性。以下是 C++20 的核心特性分類總結:

一、核心語言特性

  1. 概念(Concepts)

    • 對模板參數進行約束,提升錯誤信息可讀性:

      template <typename T>
      concept Addable = requires(T a, T b) { a + b; };  // 要求類型支持 + 操作template <Addable T>
      T sum(T a, T b) { return a + b; }  // 僅接受滿足 Addable 的類型
      
  2. 模塊(Modules)

    • 替代頭文件(#include),加快編譯速度:

      // math.ixx (模塊接口文件)
      export module math;
      export int add(int a, int b) { return a + b; }// main.cpp
      import math;
      int main() { return add(1, 2); }
      
  3. 協程(Coroutines)

    • 支持掛起/恢復的函數,簡化異步代碼:

      generator<int> range(int start, int end) {for (int i = start; i < end; ++i)co_yield i;  // 掛起并返回值
      }
      for (int i : range(1, 5)) { /*...*/ }  // 輸出 1, 2, 3, 4
      
  4. 三路比較(<=>,Spaceship Operator)

    • 簡化比較運算符定義:

      struct Point {int x, y;auto operator<=>(const Point&) const = default;  // 自動生成 ==, !=, <, > 等
      };
      
  5. 范圍 for 循環的初始化語句

    • 允許在范圍for 中定義局部變量:

      for (auto vec = get_vector(); auto& x : vec) { /*...*/ }
      
  6. constexpr 進一步擴展

    • 支持virtual函數、try-catch、動態內存分配等:

      constexpr int safe_divide(int a, int b) {if (b == 0) throw "Division by zero";  // 編譯期異常return a / b;
      }
      
  7. consteval 立即函數

    • 強制函數在編譯期執行:

      consteval int square(int x) { return x * x; }
      int arr[square(3)];  // 必須編譯期計算
      
  8. [[no_unique_address]] 屬性

    • 優化空類型成員的內存占用:

      struct Empty {};
      struct S {[[no_unique_address]] Empty e;  // 可能不占額外內存int x;
      };
      

二、標準庫增強

  1. 范圍庫(Ranges)

    • 提供管道式操作(|),簡化容器處理:

      #include <ranges>
      std::vector<int> v = {1, 2, 3, 4, 5};
      auto even = v | std::views::filter([](int x) { return x % 2 == 0; });
      for (int i : even) { /*...*/ }  // 輸出 2, 4
      
  2. std::format 格式化庫

    • 類型安全的字符串格式化(類似 Python):

      #include <format>
      std::string s = std::format("Hello, {}! The answer is {:.2f}.", "world", 3.14159);
      
  3. std::span

    • 輕量級非擁有視圖,替代原始指針 + 長度:

      void print(std::span<int> s) {for (int x : s) std::cout << x << " ";
      }
      std::vector<int> v = {1, 2, 3};
      print(v);  // 自動轉換
      
  4. std::jthread

    • 自動合并(join)的線程,避免資源泄漏:

      std::jthread t([]() { std::cout << "Thread running"; });  // 析構時自動 join
      
  5. std::atomic_ref

    • 對非原子變量的原子操作:

      int x = 0;
      std::atomic_ref<int> atomic_x(x);
      atomic_x.fetch_add(1);  // 原子操作
      
  6. 日歷和時區支持(`` 擴展)

    • 處理日期和時間:

      auto now = std::chrono::system_clock::now();
      auto today = std::chrono::floor<std::chrono::days>(now);
      std::cout << std::format("Today is {:%F}", today);  // 輸出 YYYY-MM-DD
      

三、其他重要特性

  1. constinit 關鍵字

    • 確保全局變量靜態初始化:

      constinit static int x = 42;  // 必須編譯期初始化
      
  2. 位操作庫(``)

    • 提供位運算工具:

      if (std::has_single_bit(8)) { /* 檢查是否為 2 的冪 */ }
      
  3. std::source_location

    • 替代__LINE____FILE__,獲取代碼位置:

      void log(std::source_location loc = std::source_location::current()) {std::cout << loc.file_name() << ":" << loc.line();
      }
      
  4. 協程標準庫支持

    • 提供 std::coroutine_handlestd::suspend_always 等基礎設施。

C++23(ISO/IEC 14882:2023)

C++23(ISO/IEC 14882:2023)是 C++20 之后的增量更新版本,雖然不如 C++20 那樣引入大量革命性特性,但仍包含許多實用改進,進一步簡化代碼、增強表達能力和性能。以下是 C++23 的核心特性分類總結:

一、核心語言特性

  1. #elifdef#elifndef

    • 簡化條件編譯的語法,與#ifdef/#ifndef風格一致:

      #ifdef FEATURE_A// ...
      #elifdef FEATURE_B  // 替代 #elif defined(FEATURE_B)// ...
      #endif
      
  2. auto(x)auto{x}(顯式復制構造)

    • 強制復制對象并保留類型推導:

      std::vector<int> v1 = {1, 2, 3};
      auto v2 = auto(v1);  // 顯式復制,v2 是 std::vector<int>
      
  3. 多維 operator[]mdspan 支持)

    • 允許自定義多維下標運算符:

      struct Matrix {int data[3][3];int* operator[](size_t i) { return data[i]; }int operator[](size_t i, size_t j) const { return data[i][j]; }  // C++23
      };
      Matrix m;
      m[1, 2] = 42;  // 多維訪問
      
  4. constexpr 擴展

    • 支持constexpr函數中的std::unique_ptrstd::shared_ptr(編譯期動態內存管理):

      constexpr auto create() {auto p = std::make_unique<int>(42);return *p;
      }
      static_assert(create() == 42);  // 編譯期執行
      
  5. if consteval

    • 檢測當前是否在編譯期上下文中執行:

      constexpr int foo() {if consteval { return 42; }  // 編譯期分支else { return 0; }
      }
      
  6. [[]] 屬性的位置放寬

    • 允許屬性出現在更多位置(如lambda捕獲列表前):

      auto func = [][[nodiscard]] () { return 42; };
      

二、標準庫增強

  1. std::mdspan(多維視圖)

    • 非擁有的多維數組視圖,支持靈活切片和步長:

      #include <mdspan>
      int data[2][3] = {{1, 2, 3}, {4, 5, 6}};
      std::mdspan mat(data);
      std::cout << mat[1, 2];  // 輸出 6
      
  2. std::printstd::println

    • 簡化格式化輸出(無需<format>顯式調用):

      #include <print>
      std::println("Hello, {}!", "world");  // 輸出: Hello, world!
      
  3. std::expected

    • 表示可能成功或失敗的操作(替代std::optional+ 錯誤碼):

      std::expected<int, std::string> parse_input(std::string_view s) {if (s.empty()) return std::unexpected("Empty input");return 42;
      }
      auto result = parse_input("test");
      if (result) std::println("{}", *result);
      
  4. std::generator(協程生成器)

    • 標準庫協程生成器(簡化range實現):

      #include <generator>
      std::generator<int> range(int start, int end) {for (int i = start; i < end; ++i) co_yield i;
      }
      for (int i : range(1, 5)) std::print("{} ", i);  // 輸出: 1 2 3 4
      
  5. std::flat_mapstd::flat_set

    • 基于有序向量的關聯容器(性能與內存的折衷):

      std::flat_map<int, std::string> fm = {{1, "one"}, {2, "two"}};
      fm[3] = "three";  // 自動排序
      
  6. `` 改進

    • 增強堆棧跟蹤功能(調試支持):

      #include <stacktrace>
      void foo() {auto st = std::stacktrace::current();std::println("{}", std::to_string(st));  // 打印調用棧
      }
      
  7. std::to_underlying

    • 轉換枚舉到其底層類型:

      enum class Color : uint8_t { Red = 1, Green };
      auto val = std::to_underlying(Color::Green);  // uint8_t(2)
      

三、其他實用改進

  1. std::byteswap

    • 編譯期字節交換(用于大小端轉換):

      constexpr uint32_t x = 0x12345678;
      constexpr auto y = std::byteswap(x);  // 0x78563412
      
  2. std::unreachable()

    • 標記不可達代碼(優化提示):

      if (x > 0) do_something();
      else std::unreachable();  // 假設 x 永遠 > 0
      
  3. std::move_only_function

    • 僅支持移動的函數包裝器(替代std::function的部分場景):

      std::move_only_function<int()> func = [] { return 42; };
      auto f2 = std::move(func);  // func 變為空
      
  4. std::hive(實驗性)

    • 支持指針穩定的序列容器(類似std::list但內存連續):

      std::hive<int> h = {1, 2, 3};
      auto it = h.begin(); ++it;
      h.erase(it);  // 其他迭代器仍有效
      

C++六大默認成員函數

在 C++ 中,如果一個類沒有顯式定義某些特殊成員函數,編譯器會自動生成默認版本。這些默認函數共有 6 個,通常被稱為 “六大默認成員函數”(或 “六大特殊成員函數”)。以下是它們的詳細說明:

class Example {
public:Example() = default;                 // 顯式要求生成默認構造~Example() = default;                // 顯式生成默認析構Example(const Example&) = delete;    // 禁用拷貝構造Example& operator=(Example&&) = default; // 顯式生成移動賦值ClassName& operator=(ClassName&&);
};

1. 默認構造函數 (Default Constructor)

  • 形式: ClassName()
  • 作用: 初始化對象的成員(基本類型不初始化,類類型調用其默認構造)。
  • 生成條件: 當類中沒有定義任何構造函數時生成。
  • 注意: 如果定義了其他構造函數,則不會生成默認構造,需手動添加。

2. 默認析構函數 (Destructor)

  • 形式: ~ClassName()
  • 作用: 釋放對象資源(成員變量會自動析構)。
  • 生成條件: 總是生成,除非顯式定義。
  • 注意: 若類管理動態資源(如指針),通常需要手動定義析構函數。

3. 默認拷貝構造函數 (Copy Constructor)

  • 形式: ClassName(const ClassName&)
  • 作用: 用同類型的另一個對象初始化新對象(淺拷貝)。
  • 生成條件: 當類中未顯式定義拷貝構造時生成。
  • 注意: 若類包含指針或動態資源,需手動實現深拷貝。

4. 默認拷貝賦值運算符 (Copy Assignment Operator)

  • 形式: ClassName& operator=(const ClassName&)
  • 作用: 將一個對象的值賦給另一個已存在的對象(淺拷貝)。
  • 生成條件: 當類中未顯式定義拷貝賦值時生成。
  • 注意: 類似拷貝構造,需處理深拷貝問題。

5. 默認移動構造函數 (Move Constructor) (C++11 引入)

  • 形式: ClassName(ClassName&&)
  • 作用: 通過“竊取”右值對象的資源來初始化新對象。
  • 生成條件: 當類中未顯式定義移動構造、拷貝構造、拷貝賦值、析構函數時生成。
  • 注意: 適用于優化臨時對象的資源轉移。

6. 默認移動賦值運算符 (Move Assignment Operator) (C++11 引入)

  • 形式: ClassName& operator=(ClassName&&)
  • 作用: 通過“竊取”右值對象的資源賦值給已存在對象。
  • 生成條件: 當類中未顯式定義移動賦值、拷貝構造、拷貝賦值、析構函數時生成。

總結表

默認函數形式生成條件(未顯式定義時)
默認構造函數ClassName()無任何構造函數
析構函數~ClassName()總是生成
拷貝構造函數ClassName(const ClassName&)無拷貝構造
拷貝賦值運算符ClassName& operator=(...)無拷貝賦值
移動構造函數 (C++11)ClassName(ClassName&&)無拷貝/移動構造、拷貝賦值、析構
移動賦值運算符 (C++11)ClassName& operator=(...)無拷貝/移動賦值、拷貝構造、析構

關鍵注意事項

  1. 淺拷貝問題:默認拷貝構造和拷貝賦值是淺拷貝,可能引發雙重釋放(需手動實現深拷貝)。
  2. Rule of Three/Five/Zero
    • 如果定義了拷貝構造、拷貝賦值或析構中的任意一個,通常需要定義全部(C++03)。
    • 在 C++11 后,還需考慮移動構造和移動賦值(Rule of Five)。
    • 最佳實踐是使用 =default=delete 明確需求,或遵循 Rule of Zero(依賴智能指針等自動管理資源)。
  3. =default=delete
    • 可用 =default 顯式要求編譯器生成默認實現。
    • =delete 禁止特定函數(如禁用拷貝)。

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

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

相關文章

詞編碼模型怎么進行訓練的,輸出輸入是什么,標簽是什么

詞編碼模型怎么進行訓練的,輸出輸入是什么,標簽是什么 詞編碼模型的訓練本質是通過數據驅動的方式,將離散的文本符號映射為連續的語義向量。 一、訓練機制:從符號到向量的映射邏輯 1. 核心目標 將單詞/子詞(Token)映射為低維向量,使語義相關的詞在向量空間中距離更近…

【Linux指南】文件管理高級操作(復制、移動、查找)

引言 在Linux系統管理中&#xff0c;文件的復制、移動與查找是比基礎操作更進階的核心技能&#xff0c;它們構成了高效管理文件系統的"三駕馬車"。當我們需要備份重要數據、重構目錄結構或在龐大的文件系統中定位目標文件時&#xff0c;cp、mv、find等命令將成為最得…

【棧】-----【小C的記事本】

小C的記事本 題目描述 小C最近學會了 Java 小程序的開發&#xff0c;他很開心&#xff0c;于是想做一個簡單的記事本程序練練手。 他希望他的記事本包含以下功能&#xff1a; append(str)&#xff1a;向記事本插入字符串 str&#xff08;英文字符&#xff09;。delete(k)&am…

技能系統詳解(2)——特效表現

特效會有個EffectManager用于統一管理所有特效&#xff0c;技能特效只是各類特效中的一種 EffectManager需要提供特效的創建&#xff0c;返回被封裝為EffectHandle 每類特效都有各種不同的配置參數&#xff0c;這些配置參數會傳遞給EffectManager用于生成EffectHandler 為支…

12.OpenCV—基礎入門

01讀取圖像 02創建空白圖像 03保存圖像 04更改圖像亮度 05更改圖像對比度 06灰度直方圖均衡 07彩色直方圖均衡 08五種濾波方式 09形態學操作 10仿射變換 11角度縮放仿射變換 12透視變換 13坐標映射 14模板匹配 15多模板匹配 16查找輪廓線 17輪廓線匹配 17繪制…

【Python】Python之什么是生成器?什么是迭代器?

目錄 專欄導讀前言什么是迭代器&#xff08;Iterator&#xff09;&#xff1f;迭代器的定義迭代器協議可迭代對象 vs 迭代器自定義迭代器迭代器的優勢 什么是生成器&#xff08;Generator&#xff09;&#xff1f;生成器的定義生成器函數生成器表達式復雜的生成器示例生成器的狀…

Python中實現簡單爬蟲并處理數據

在當今數據驅動的時代&#xff0c;能夠從互聯網上高效地抓取信息變得越來越重要。Python因其簡潔易學的特性&#xff0c;成為了編寫網絡爬蟲的首選語言之一。接下來&#xff0c;我將介紹如何使用Python來實現一個基礎的網絡爬蟲&#xff0c;并對收集到的數據進行初步處理。 首先…

免費wordpress主題網

免費WordPress主題網 WP模板牛 WP模板牛是一個提供免費WordPress主題的網站&#xff0c;用戶可以在這里找到大量高質量的模板&#xff0c;適用于各種網站類型。該網站致力于為用戶提供簡單、高效的建站體驗。 官網鏈接&#xff1a; https://wpniu.com 建站哥模板 建站哥模板…

為什么需要MyBatis-Plus條件構造器?

目錄 前言 一、傳統SQL編寫的痛點 二、條件構造器的核心優勢 1. 防SQL注入&#xff08;安全性&#xff09; 2. 面向對象編程&#xff08;可讀性&#xff09; 3. 動態條件構建&#xff08;靈活性&#xff09; 4. 數據庫無關性&#xff08;可移植性&#xff09; 三、典型應…

【從零學習JVM|第九篇】常見的垃圾回收算法和垃圾回收器

前言&#xff1a; 我們知道在堆內存中&#xff0c;會有自動的垃圾回收功能&#xff0c;那今天這篇文章將會向你介紹&#xff0c;這個功能實現的方式&#xff0c;還有實現的對象&#xff0c;接下來就由我來給你們詳細介紹垃圾回收的算法和實現算法的回收器。 目錄 前言&#…

品牌竄貨治理解決方案

在渠道網絡的暗潮中&#xff0c;竄貨猶如隱秘的漩渦&#xff0c;某知名白酒品牌曾因區域竄貨導致終端價格體系崩潰&#xff0c;半年內損失超3億元。竄貨行為不僅破壞市場秩序&#xff0c;更會引發信任危機。隨著電商平臺的多元化與分銷層級的復雜化&#xff0c;品牌方亟需構建一…

車載電子電器架構 --- 法律和標準對電子電氣架構的影響

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

一種通用跨平臺實現SEH的解決方案

一. 前言 眾所周知&#xff0c;在軟件的代碼中&#xff0c;處理軟件本身的邏輯只要大約1/3的代碼&#xff0c;另外2/3的代碼實際上是在處理各種各樣的異常情況。 這些異常情況一方面是因為不同用戶之間不同的硬件軟件環境要處理。另一方面是程序中可能出現的bug。比較典型的情…

25.6.19學習總結

什么是堆&#xff08;Heap&#xff09;&#xff1f; 堆是一種特殊的樹形數據結構&#xff0c;它滿足以下兩個主要屬性&#xff1a; 結構性&#xff08;完全二叉樹&#xff09;&#xff1a; 堆總是一個完全二叉樹 (Complete Binary Tree)。這意味著&#xff0c;除了最后一層&am…

【前后前】導入Excel文件閉環模型:Vue3前端上傳Excel文件,【Java后端接收、解析、返回數據】,Vue3前端接收展示數據

【前后前】導入Excel文件閉環模型&#xff1a;Vue3前端上傳Excel文件&#xff0c;【Java后端接收、解析、返回數據】&#xff0c;Vue3前端接收展示數據 一、Vue3前端上傳&#xff08;導入&#xff09;Excel文件 ReagentInDialog.vue <script setup lang"ts" na…

網絡基礎入門:從OSI模型到TCP/IP協議詳解

網絡基礎入門&#xff1a;從OSI模型到TCP/IP協議詳解 一、網絡基礎概念與OSI七層模型 1.1 網絡通信的本質 計算機網絡的核心是將抽象語言轉換為二進制數據進行傳輸與計算&#xff0c;這一過程涉及多層抽象與轉換&#xff1a; 應用層&#xff1a;人機交互—抽象語言------編…

Linux致命漏洞CVE-2025-6018和CVE-2025-6019

Qualys 最近披露了兩個影響主流 Linux 發行版的本地權限提升 (LPE) 漏洞&#xff0c;分別是 CVE-2025-6018 和 CVE-2025-6019。這兩個漏洞可以被串聯利用&#xff0c;使得非特權用戶在幾秒鐘內獲得系統的 root 權限&#xff0c;從而實現對系統的完全控制。 一、漏洞詳情 這兩…

【Docker基礎】Docker鏡像管理:docker push詳解

目錄 引言 1 Docker鏡像推送基礎概念 1.1 什么是Docker鏡像推送 1.2 鏡像倉庫概述 1.3 鏡像標簽與版本控制 2 docker push命令詳解 2.1 基本語法 2.2 常用參數選項 2.3 實際命令示例 2.4 推送流程 2.5 步驟描述 3 鏡像推送實踐示例 3.1 登錄管理 3.2 標簽管理 3…

FPGA基礎 -- Verilog行為建模之循環語句

行為級建模&#xff08;Behavioral Modeling&#xff09;是 Verilog HDL 中最接近軟件編程語言的一種描述方式&#xff0c;適用于功能建模和仿真建模的初期階段。在行為級中&#xff0c;循環語句&#xff08;loop statements&#xff09;是常見且重要的控制結構&#xff0c;用于…

從C學C++(7)——static成員

從C學C(7)——static成員 若無特殊說明&#xff0c;本博客所執行的C標準均為C11. static成員和成員函數 對于特定類型的全體對象而言&#xff0c;有時候可能需要訪問一個全局的變量。比如說統計某種類型對象已創建的數量。 通常在C中使用全局變量來實現&#xff0c;如果我們…