日本免费精品_最新日韩一区_亚洲视频一区在线_a在线视频观看_天天射夜夜骑_粉嫩av一区二区三区_欧美中日韩免费视频_综合图区欧美_国内精品美女在线观看_午夜精品久久久久久久男人的天堂

首頁 > 編程 > C++ > 正文

詳解C++中對構造函數和賦值運算符的復制和移動操作

2020-05-23 14:09:39
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++中對構造函數和賦值運算符的復制和移動,是C++入門學習中的基礎知識,需要的朋友可以參考下
 

復制構造函數和復制賦值運算符
從 C++ 11 中開始,該語言支持兩種類型的分配:復制賦值和移動賦值。 在本文中,“賦值”意味著復制賦值,除非有其他顯式聲明。 賦值操作和初始化操作都會導致對象被復制。
賦值:在將一個對象的值賦給另一個對象時,第一個對象將復制到第二個對象中。 因此,

Point a, b;...a = b;

導致 b 的值被復制到 a 中。
初始化:在以下情況下將進行初始化:聲明新對象、參數通過值傳遞給函數或值通過值從函數返回。
您可以為類類型的對象定義“復制”的語義。 例如,考慮此代碼:

TextFile a, b;a.Open( "FILE1.DAT" );b.Open( "FILE2.DAT" );b = a;

前面的代碼可能表示“將 FILE1.DAT 的內容復制到 FILE2.DAT”,也可能表示“忽略 FILE2.DAT 并使 b 成為 FILE1.DAT 的另一個句柄”。 您必須將適當的復制語義附加到每個類,如下所示。
通過將賦值運算符 operator= 與對類類型的引用一起用作返回類型和 const 引用所傳遞的參數(例如,ClassName& operator=(const ClassName& x);)。
通過通過復制構造函數。 有關復制構造函數的詳細信息,請參閱聲明構造函數的規則。
如果不聲明復制構造函數,編譯器將為你生成 member-wise 復制構造函數。  如果不聲明復制賦值運算符,編譯器將為你生成 member-wise 復制賦值運算符。 聲明復制構造函數不會取消編譯器生成的復制賦值運算符,反之亦然。 如果實現上述其中一項,建議您還實現另一項以使代碼的含義變得明確。
逐個成員賦值和初始化 中更詳細地介紹了逐個成員賦值。
復制構造函數采用了 class-name& 類型的參數,其中 class-name 是為其定義構造函數的類的名稱。 例如:

// spec1_copying_class_objects.cppclass Window{public: Window( const Window& ); // Declare copy constructor. // ...};int main(){}

說明:
盡可能創建該類型的復制構造函數的參數 const class-name&。 這可防止復制構造函數意外更改從中復制它的對象。 它還支持從 const 對象進行復制。
編譯器生成的構造函數
編譯器生成的復制構造函數(如用戶定義的復制構造函數)具有單個參數類型“對 class-name 的引用”。 當所有基類和成員類都具有聲明為采用 const class-name& 類型的單個參數的復制構造函數時,將引發異常。 在這種情況下,編譯器生成的復制構造函數的參數也是 const。
當復制構造函數的參數類型不是 const 時,通過復制 const 對象進行初始化將產生錯誤。 反之則不然:如果參數是 const,您可以通過復制不是 const 的對象進行初始化。
編譯器生成的賦值運算符遵循關于 const 的相同模式。 除非所有基類和成員類中的賦值運算符都采用 const class-name& 類型的參數,否則它們將采用 class-name& 類型的單個參數。 在這種情況下,類的生成的賦值運算符采用 const 參數。
說明:
當虛擬基類由復制構造函數(編譯器生成或用戶定義的)初始化時,將只初始化這些基類一次:在構造它們時。
含義類似于復制構造函數的含義。 當參數類型不是 const 時,從 const 對象賦值將產生錯誤。 反之則不然:如果將 const 值賦給不是 const 的值,則賦值能成功。

移動構造函數和移動賦值運算符
下面的示例基于用于管理內存緩沖區的 C++ 類 MemoryBlock。

// MemoryBlock.h#pragma once#include <iostream>#include <algorithm>class MemoryBlock{public: // Simple constructor that initializes the resource. explicit MemoryBlock(size_t length)  : _length(length)  , _data(new int[length]) {  std::cout << "In MemoryBlock(size_t). length = "    << _length << "." << std::endl; } // Destructor. ~MemoryBlock() {  std::cout << "In ~MemoryBlock(). length = "    << _length << ".";  if (_data != nullptr)  {   std::cout << " Deleting resource.";   // Delete the resource.   delete[] _data;  }  std::cout << std::endl; } // Copy constructor. MemoryBlock(const MemoryBlock& other)  : _length(other._length)  , _data(new int[other._length]) {  std::cout << "In MemoryBlock(const MemoryBlock&). length = "     << other._length << ". Copying resource." << std::endl;  std::copy(other._data, other._data + _length, _data); } // Copy assignment operator. MemoryBlock& operator=(const MemoryBlock& other) {  std::cout << "In operator=(const MemoryBlock&). length = "     << other._length << ". Copying resource." << std::endl;  if (this != &other)  {   // Free the existing resource.   delete[] _data;   _length = other._length;   _data = new int[_length];   std::copy(other._data, other._data + _length, _data);  }  return *this; } // Retrieves the length of the data resource. size_t Length() const {  return _length; }private: size_t _length; // The length of the resource. int* _data; // The resource.};

以下過程介紹如何為示例 C++ 類編寫移動構造函數和移動賦值運算符。
為 C++ 創建移動構造函數
定義一個空的構造函數方法,該方法采用一個對類類型的右值引用作為參數,如以下示例所示:

MemoryBlock(MemoryBlock&& other) : _data(nullptr) , _length(0){}

在移動構造函數中,將源對象中的類數據成員添加到要構造的對象:

_data = other._data;_length = other._length;

將源對象的數據成員分配給默認值。 這樣可以防止析構函數多次釋放資源(如內存):

other._data = nullptr;other._length = 0;

為 C++ 類創建移動賦值運算符
定義一個空的賦值運算符,該運算符采用一個對類類型的右值引用作為參數并返回一個對類類型的引用,如以下示例所示:

MemoryBlock& operator=(MemoryBlock&& other){}

在移動賦值運算符中,如果嘗試將對象賦給自身,則添加不執行運算的條件語句。

if (this != &other){}

在條件語句中,從要將其賦值的對象中釋放所有資源(如內存)。
以下示例從要將其賦值的對象中釋放 _data 成員:

// Free the existing resource.delete[] _data;

執行第一個過程中的步驟 2 和步驟 3 以將數據成員從源對象轉移到要構造的對象:

// Copy the data pointer and its length from the // source object._data = other._data;_length = other._length;// Release the data pointer from the source object so that// the destructor does not free the memory multiple times.other._data = nullptr;other._length = 0;

返回對當前對象的引用,如以下示例所示:

return *this;

以下示例顯示了 MemoryBlock 類的完整移動構造函數和移動賦值運算符:

// Move constructor.MemoryBlock(MemoryBlock&& other) : _data(nullptr) , _length(0){ std::cout << "In MemoryBlock(MemoryBlock&&). length = "     << other._length << ". Moving resource." << std::endl; // Copy the data pointer and its length from the  // source object. _data = other._data; _length = other._length; // Release the data pointer from the source object so that // the destructor does not free the memory multiple times. other._data = nullptr; other._length = 0;}// Move assignment operator.MemoryBlock& operator=(MemoryBlock&& other){ std::cout << "In operator=(MemoryBlock&&). length = "     << other._length << "." << std::endl; if (this != &other) {  // Free the existing resource.  delete[] _data;  // Copy the data pointer and its length from the   // source object.  _data = other._data;  _length = other._length;  // Release the data pointer from the source object so that  // the destructor does not free the memory multiple times.  other._data = nullptr;  other._length = 0; } return *this;}

以下示例演示移動語義如何能提高應用程序的性能。此示例將兩個元素添加到一個矢量對象,然后在兩個現有元素之間插入一個新元素。在 Visual C++ 2010 中,vector 類使用移動語義,通過移動矢量元素(而非復制它們)來高效地執行插入操作。

// rvalue-references-move-semantics.cpp// compile with: /EHsc#include "MemoryBlock.h"#include <vector>using namespace std;int main(){ // Create a vector object and add a few elements to it. vector<MemoryBlock> v; v.push_back(MemoryBlock(25)); v.push_back(MemoryBlock(75)); // Insert a new element into the second position of the vector. v.insert(v.begin() + 1, MemoryBlock(50));}
 

該示例產生下面的輸出:

In MemoryBlock(size_t). length = 25.In MemoryBlock(MemoryBlock&&). length = 25. Moving resource.In ~MemoryBlock(). length = 0.In MemoryBlock(size_t). length = 75.In MemoryBlock(MemoryBlock&&). length = 25. Moving resource.In ~MemoryBlock(). length = 0.In MemoryBlock(MemoryBlock&&). length = 75. Moving resource.In ~MemoryBlock(). length = 0.In MemoryBlock(size_t). length = 50.In MemoryBlock(MemoryBlock&&). length = 50. Moving resource.In MemoryBlock(MemoryBlock&&). length = 50. Moving resource.In operator=(MemoryBlock&&). length = 75.In operator=(MemoryBlock&&). length = 50.In ~MemoryBlock(). length = 0.In ~MemoryBlock(). length = 0.In ~MemoryBlock(). length = 25. Deleting resource.In ~MemoryBlock(). length = 50. Deleting resource.In ~MemoryBlock(). length = 75. Deleting resource.

使用移動語義的此示例版本比不使用移動語義的版本更高效,因為前者執行的復制、內存分配和內存釋放操作更少。
可靠編程
若要防止資源泄漏,請始終釋放移動賦值運算符中的資源(如內存、文件句柄和套接字)。
若要防止不可恢復的資源損壞,請正確處理移動賦值運算符中的自我賦值。
如果為您的類同時提供了移動構造函數和移動賦值運算符,則可以編寫移動構造函數來調用移動賦值運算符,從而消除冗余代碼。以下示例顯示了調用移動賦值運算符的移動構造函數的修改后的版本:

// Move constructor.MemoryBlock(MemoryBlock&& other) : _data(nullptr) , _length(0){ *this = std::move(other);}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
欧美99久久| 二区视频在线观看| 中文字幕日韩欧美| 在线观看国产一级片| 国产亚洲欧美色| 中文字幕在线视频日韩| 亚洲va久久久噜噜噜久久| 伊人国产视频| 国产字幕在线看| 97天天综合网| 91精品国产入口| 亚洲一区在线观看免费| 中文字幕欧美日韩精品| 中文字幕亚洲区| 精品一二线国产| 尤物av一区二区| 国产午夜精品久久| 日本精品福利视频| 最近中文av字幕在线中文| 国产福利第一页| 在线视频一区二区三区在线播放| 国产中文伊人| 亚洲热线99精品视频| 日韩欧美亚洲国产一区| 欧美日韩综合色| 国产字幕在线看| 欧美国产中文| 欧美日韩国产中文精品字幕自在自线 | 在线综合 亚洲 欧美中文字幕| 欧美日韩国产片| 精品亚洲综合| 国产在线欧美日韩| 久久99精品久久久| www.91香蕉视频| 一区二区三区免费看视频| 日韩亚洲欧美中文高清在线| 最近免费中文字幕在线第一页| 欧美91精品| 韩日中文字幕第一页| 色综合婷婷久久| 亚洲丝袜一区| 精品全国在线一区二区| 久久久精品福利| 中文字幕亚洲国产| 日韩精品高清不卡| 国产高清一级片| 国产小视频在线| 日韩国产一区久久| 日韩亚洲欧美中文在线| 一区二区三区在线不卡| 亚洲一区激情| av最新网址| 日韩精品在线免费看| 国产欧美综合在线| 亚洲欧美韩国综合色| 久久久另类综合| 精品乱人伦一区二区三区| 日韩精品a在线观看91| √新版天堂资源在线资源| 欧美在线视频第一页| 欧美中文字幕在线观看视频| 91麻豆精品在线| 91久久精品国产91性色69| 欧美日韩亚洲一| 国产成人精品亚洲| 国产在线不卡av| 中文字幕第一页在线播放| 中文字幕在线播放一区| 亚洲国产欧美91| 亚洲羞羞网站| 中文字幕第一页在线| 欧美日韩国产亚洲一区| 精品国产乱码久久久久久蜜臀| 国产一区激情在线| 国产在线导航| 91精品啪在线观看国产60岁| 国产福利在线看| 亚洲一区在线观看网站| 亚洲一区中文在线| 欧美日韩精品国产| 国产www.大片在线| 国产黄色精品| 国内精品不卡| 国产超级va在线视频| 日韩精品免费视频一区二区三区| 日韩高清不卡一区| 中文在线不卡视频| 日韩欧美三级视频| 免费高清在线一区| 日韩欧美国产免费播放| 日韩一级在线视频| 中文字幕国产亚洲| 91色在线看| 欧美亚洲国产日韩2020| 国产欧美一级| 亚洲国产无线乱码在线观看| 91一区二区| 日韩欧美不卡在线| 中文字幕欧美日韩在线| 中文字幕在线视频第一页| 日韩欧美一级二级三级久久久| 欧美亚洲免费高清在线观看| 精品视频www| 1024国产在线| 中文字幕伊人| 精品一区二区在线观看视频| 精品网站999www| 欧美日韩综合高清一区二区 | 国产久卡久卡久卡久卡视频精品| 99久久精品国产成人一区二区| 日韩欧美一级在线播放| 在线视频三区| 国产无套粉嫩白浆在线2022年| 91精品国产免费久久综合| 亚洲免费专区| 欧美日本精品| 精品国产乱码久久久久久蜜臀| 伊人网站在线| 欧美日韩视频免费看| 在线观看国产福利视频| 欧美乱大交xxxxx免费| 91精品在线视频观看| 欧美中文字幕视频在线观看 | 日本亚洲欧美三级| 久久精品国产91精品亚洲| 中文字幕日韩高清| 欧美三级免费观看| 久99久视频| 亚洲视频色图| 中文字幕一区不卡| 久久精品国产视频| 国产一级片网站| 日韩欧美在线第一页| 精品网站999www| 欧美日韩高清一区二区不卡| 国产在线高清精品| 国产网站av| 日韩三级高清在线| 日韩精品在线网站| 日韩亚洲不卡在线| 日韩在线高清| 欧美日韩中文另类| 日本a口亚洲| 欧美国产亚洲一区| 日韩欧美在线网址| 久草视频在线看| 精品国产免费视频| 久久99久久99精品中文字幕| 亚洲中午字幕| 日韩一级中文字幕| aaa欧美日韩| 国产不卡在线| 欧美中文字幕精品| 久久精品不卡| 国产一级久久久| 日韩欧美在线字幕| 亚洲社区在线| 精品激情国产视频| 亚洲高清视频在线| 中文在线不卡| 一区二区三区在线|网站| 欧美日韩国产片| 福利一区二区| 午夜av一区| 亚洲乱码在线观看| 日韩不卡一二区| 欧美国产一区视频在线观看| 亚洲校园欧美国产另类| 欧美日韩国产片| 国产一二三精品| 日韩欧美中文第一页| 国产婷婷精品| 精品在线网站观看| 欧美日韩亚洲不卡| 国产福利精品导航| 亚洲专区一二三| 中文字幕视频一区二区三区久| 日韩精品欧美| 日韩午夜黄色| 久久人人精品| 精品一二三区| 欧美日韩精品中文字幕| 一区二区三区中文字幕在线观看| 国产黄色一区| 一二三区精品福利视频| 一本一道久久a久久精品综合蜜臀 一本一道综合狠狠老 | 91精品国产色综合久久久蜜香臀| 欧美亚洲专区| 亚洲高清免费一级二级三级| 91精品国产亚洲| 高清中文字幕在线| 久久电影国产免费久久电影| 欧美日韩中文字幕| 在线免费播放av| 欧美在线观看视频一区| 日韩精品一区二区三区视频播放| 亚洲美女视频一区| 亚洲国产午夜精品| 蜜臀久久精品| 久久久99精品久久| 欧美日韩亚洲第一| 国产丝袜一区| 日韩视频在线免费看| 国产裸舞福利在线视频合集| 久久婷婷国产| 国产区高清在线| 国产欧美日韩不卡| 国产一卡2卡3卡4卡网站免费| 日韩欧美中文字幕公布| 久久精品国产视频| 久久香蕉精品| 在线视频日韩欧美| 中文字幕亚洲视频| 免费视频国产一区| 免费看黄资源大全高清| 日韩欧美在线视频日韩欧美在线视频| 欧美中文字幕视频在线观看 | 91精品国产色综合久久久蜜香臀| 久久精品人妻一区二区三区| 国内不卡的二区三区中文字幕| 日韩 欧美 综合| 亚洲精品中文字幕乱码三区| 日本а中文在线天堂| 日韩专区中文字幕| 一二三区精品福利视频| 亚洲欧美视频一区二区三区| 中文字幕国产欧美| 日韩在线不卡一区| 91极品视频在线观看| 在线不卡一区二区| 欧美日韩视频在线| 欧美日韩精品久久久| 精品一二线国产| 精品一二三四区| 中文字幕欧美日韩在线| 色综合天天性综合| 国产婷婷色一区二区三区在线| 中文在线一区| 国产91一区| 欧美日韩一二三| 亚洲一区资源| 亚洲成年人影院在线| 日韩精品福利一区二区三区| 欧美91精品| 国产欧美日韩精品高清二区综合区| 国产91久久久久| 中文在线不卡| 亚洲免费在线视频一区 二区| 久久99精品久久久| 欧美 日韩 国产 在线观看| 国产一级在线播放| 欧美1区免费| 国产高清在线一区| 国产在线播放一区二区| 一级免费a一片| 中文字幕亚洲一区在线观看| 国产偷久久久精品专区| 国产69精品久久久久孕妇国产69久久 | 91精品国产日韩91久久久久久| 自拍日韩亚洲一区在线| 午夜一区二区视频| 久久综合九色欧美综合狠狠| 国产亚洲人成a一在线v站| www.狠狠| 国产91大片| 三级网站免费观看| 正在播放日韩精品| 欧美高清一级片在线| 高清1区2区| 久久久久久91| 欧美日韩精品高清| 国产高清视频一区二区| 中文网丁香综合网| 日韩精品视频免费| www 日韩| 欧美日韩乱国产| 日韩欧美色综合| 日韩不卡高清视频| 91精品国产综合久久久久久漫画 | 一区二区在线高清视频| 免费视频久久| 欧美日韩在线播放视频| 中文字幕在线观看精品| 日韩免费精品视频| 日韩在线视频免费观看高清中文| 国产丝袜一区二区| 中文字幕人成乱码在线观看| 国产一级久久久| 一区二区视频在线| 日韩中文首页| 在线日韩欧美| 精品av中文字幕在线毛片| 99精品一级欧美片免费播放| 色综合天天性综合| 一区二区三区免费看视频| 婷婷精品进入| 国产99精品| 日韩欧美中文在线| 午夜伦欧美伦电影理论片| 久久精品女人| 久久99精品国产| 一区二区视频在线| www日韩欧美| 欧美国产一级片| 日韩精品视频免费播放| 中文字幕在线导航| 国产三级做爰在线观看| 黄色欧美日韩| 国产乱国产乱300精品| 色综合久久六月婷婷中文字幕| 欧美日韩国产亚洲一区| 国产色综合网| 一区视频在线播放| 欧美一级日韩不卡播放免费| 91精品国产91久久久久久不卡 | 精品国产99| 亚洲美女视频一区| 91日韩中文字幕| 中文精品视频| 欧美日韩高清不卡| 国产在线一区二区视频| 日韩高清不卡一区二区| 日韩欧美国产视频| 一级免费a一片| 久久久99久久| 日韩欧美三级视频| 欧美日韩一级片在线观看| 欧美日韩亚洲一| 国产一区成人| 日韩在线中文字幕| 精品国产网站在线观看| 中文字幕在线日韩| 中文字幕五月天| 久久久另类综合| 亚洲校园欧美国产另类| 色一区在线观看| 日韩欧美国产高清| 成人久久久久| 日韩欧美亚洲视频| 午夜一区二区三区| 国产欧美日产一区| 国产91久久久久蜜臀青青天草二| 日韩精品在线看| 91亚洲国产| 国产在成人精品线拍偷自揄拍| 精品国产欧美| 国产激情在线| 国产三级精品在线观看| 欧美日韩久久不卡| 日韩精品视频免费| 三级精品视频| 天天在线视频色| 精品999视频| 日本精品国语自产拍在线观看| 欧美日韩精品综合在线| 午夜视频在线观看一区| 久久久99久久精品欧美| 国产成人一区二区精品非洲| 日韩精品在线观| 中文字幕在线看视频国产欧美| 视频一区二区不卡| 亚洲成年人在线播放| 中文字幕综合在线| 中文字幕亚洲一区二区av在线| 中文字幕欧美亚洲| 中文字幕久久精品| 91精品在线看V| 国产一级久久久| 91精品国产自产在线观看永久∴ | 日韩久久久精品| 99久久婷婷| 福利一区二区| 欧美日本精品在线| √天堂资源中文www| 国产欧美日韩精品高清二区综合区 | 亚洲综合三区| 激情婷婷亚洲| 欧美日韩国产成人| 亚洲黄色片在线观看| 日韩.com| 欧美精品一区二区三区在线播放| 91麻豆视频网站| 不卡av免费在线| 亚洲一级在线| 国产福利不卡| 极品久久久久久| 日韩在线a电影| 久久久久久欧美| 亚洲一区二区三区精品中文字幕| 久久精品网站免费观看| 狠狠色综合色区| 国产免费永久在线观看| 精品视频123区在线观看| 国产欧美久久久| 亚洲欧美中文字幕在线观看| 日本视频久久久| 日本精品在线| 91精品国产91久久久久久不卡| 午夜精品一区二区三区视频免费看| 亚洲一二三不卡|