亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

詳解在C++中顯式默認設置的函數和已刪除的函數的方法

2020-05-23 14:09:57
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了在C++中顯式默認設置的函數和已刪除的函數的方法,文中講到了C++11標準中的新特性,需要的朋友可以參考下
 

在 C++11 中,默認函數和已刪除函數使你可以顯式控制是否自動生成特殊成員函數。已刪除的函數還可為您提供簡單語言,以防止所有類型的函數(特殊成員函數和普通成員函數以及非成員函數)的參數中出現有問題的類型提升,這會導致意外的函數調用。
顯式默認設置的函數和已刪除函數的好處
在 C++ 中,如果某個類型未聲明它本身,則編譯器將自動為該類型生成默認構造函數、復制構造函數、復制賦值運算符和析構函數。這些函數稱為特殊成員函數,它們使 C++ 中的簡單用戶定義類型的行為如同 C 中的結構。也就是說,可以創建、復制和銷毀它們而無需任何額外編碼工作。C++11 會將移動語義引入語言中,并將移動構造函數和移動賦值運算符添加到編譯器可自動生成的特殊成員函數的列表中。
這對于簡單類型非常方便,但是復雜類型通常自己定義一個或多個特殊成員函數,這可以阻止自動生成其他特殊成員函數。實踐操作:

  • 如果顯式聲明了任何構造函數,則不會自動生成默認構造函數。
  • 如果顯式聲明了虛擬析構函數,則不會自動生成默認析構函數。
  • 如果顯式聲明了移動構造函數或移動賦值運算符,則:
  1. 不自動生成復制構造函數。
  2. 不自動生成復制賦值運算符。
  • 如果顯式聲明了復制構造函數、復制賦值運算符、移動構造函數、移動賦值運算符或析構函數,則:
  1. 不自動生成移動構造函數。
  2. 不自動生成移動賦值運算符。

注意

此外,C++11 標準指定將以下附加規則:

  • 如果顯式聲明了復制構造函數或析構函數,則棄用復制賦值運算符的自動生成。
  • 如果顯式聲明了復制賦值運算符或析構函數,則棄用復制構造函數的自動生成。
  • 在這兩種情況下,Visual Studio 將繼續隱式自動生成所需的函數且不發出警告。

這些規則的結果也可能泄漏到對象層次結構中。例如,如果基類因某種原因無法擁有可從派生類調用的默認構造函數 - 也就是說,一個不采用任何參數的 public 或 protected 構造函數 - 那么從基類派生的類將無法自動生成它自己的默認構造函數。

這些規則可能會使本應直接的內容、用戶定義類型和常見 C++ 慣例的實現變得復雜 — 例如,通過以私有方式復制構造函數和復制賦值運算符,而不定義它們,使用戶定義類型不可復制。

struct noncopyable{ noncopyable() {};private: noncopyable(const noncopyable&); noncopyable& operator=(const noncopyable&);};

在 C++11 之前,此代碼段是不可復制的類型的慣例形式。但是,它具有幾個問題:
復制構造函數必須以私有方式進行聲明以隱藏它,但因為它進行了完全聲明,所以會阻止自動生成默認構造函數。如果你需要默認構造函數,則必須顯式定義一個(即使它不執行任何操作)。
即使顯式定義的默認構造函數不執行任何操作,編譯器也會將它視為重要內容。其效率低于自動生成的默認構造函數,并且會阻止 noncopyable 成為真正的 POD 類型。
盡管復制構造函數和復制賦值運算符在外部代碼中是隱藏的,但成員函數和 noncopyable 的友元仍可以看見并調用它們。如果它們進行了聲明但是未定義,則調用它們會導致鏈接器錯誤。
雖然這是廣為接受的慣例,但是除非你了解用于自動生成特殊成員函數的所有規則,否則意圖不明確。
在 C++11 中,不可復制的習語可通過更直接的方法實現。

struct noncopyable{ noncopyable() =default; noncopyable(const noncopyable&) =delete; noncopyable& operator=(const noncopyable&) =delete;};

請注意如何解決與 C++11 之前的慣例有關的問題:
仍可通過聲明復制構造函數來阻止生成默認構造函數,但可通過將其顯式設置為默認值進行恢復。
顯式設置的默認特殊成員函數仍被視為不重要的,因此性能不會下降,并且不會阻止 noncopyable 成為真正的 POD 類型。
復制構造函數和復制賦值運算符是公共的,但是已刪除。定義或調用已刪除函數是編譯時錯誤。
對于了解 =default 和 =delete 的人來說,意圖是非常清楚的。你不必了解用于自動生成特殊成員函數的規則。
對于創建不可移動、只能動態分配或無法動態分配的用戶定義類型,存在類似慣例。所有這些慣例都具有 C++11 之前的實現,這些實現會遭受類似問題,并且可在 C++11 中通過按照默認和已刪除特殊成員函數實現它們,以類似方式進行解決。
顯式默認設置的函數
可以默認設置任何特殊成員函數 — 以顯式聲明特殊成員函數使用默認實現、定義具有非公共訪問限定符的特殊成員函數或恢復其他情況下被阻止其自動生成的特殊成員函數。
可通過如此示例所示進行聲明來默認設置特殊成員函數:

struct widget{ widget()=default; inline widget& operator=(const widget&);};inline widget& widget::operator=(const widget&) =default;

 

請注意,只要特殊成員函數可內聯,便可以在類主體外部默認設置它。
由于普通特殊成員函數的性能優勢,因此我們建議你在需要默認行為時首選自動生成的特殊成員函數而不是空函數體。你可以通過顯式默認設置特殊成員函數,或通過不聲明它(也不聲明其他會阻止它自動生成的特殊成員函數),來實現此目的。
注意
Visual Studio 不支持默認的移動構造函數或移動賦值運算符作為 C++11 標準授權。有關詳細信息,請參閱 支持 C++11/14/17 功能(現代 C++)中的“默認函數和已刪除的函數”一節。
已刪除的函數
可以刪除特殊成員函數以及普通成員函數和非成員函數,以阻止定義或調用它們。通過刪除特殊成員函數,可以更簡潔地阻止編譯器生成不需要的特殊成員函數。必須在聲明函數時將其刪除;不能在這之后通過聲明一個函數然后不再使用的方式來將其刪除。

struct widget{ // deleted operator new prevents widget from being dynamically allocated. void* operator new(std::size_t) = delete;};

刪除普通成員函數或非成員函數可阻止有問題的類型提升導致調用意外函數。這可發揮作用的原因是,已刪除的函數仍參與重載決策,并提供比提升類型之后可能調用的函數更好的匹配。函數調用將解析為更具體的但可刪除的函數,并會導致編譯器錯誤。

// deleted overload prevents call through type promotion of float to double from succeeding.void call_with_true_double_only(float) =delete;void call_with_true_double_only(double param) { return; }

請注意,在前面的示例中,使用 call_with_true_double_only 參數調用 float 將導致編譯器錯誤,但使用 call_with_true_double_only 參數調用 int 不會導致編譯器錯誤;在 int 示例中,此參數將從 int 提升到 double,并成功調用函數的 double 版本,即使這可能并不是預期目的。若要確保使用非雙精度參數對此函數進行的任何調用均會導致編譯器錯誤,您可以聲明已刪除的函數的模板版本。

template < typename T >void call_with_true_double_only(T) =delete; //prevent call through type promotion of any T to double from succeeding.void call_with_true_double_only(double param) { return; } // also define for const double, double&, etc. as needed.
 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲欧美另类中文| 成人福利网站在线观看11| 91精品国产综合久久香蕉最新版| 最近2019中文字幕mv免费看| 日韩乱码在线视频| 亚洲片在线资源| 日韩在线观看免费高清完整版| 亚洲精品国产精品国自产在线| 91久久嫩草影院一区二区| 红桃av永久久久| 欧美激情精品久久久久久黑人| 亚洲а∨天堂久久精品9966| www.日韩.com| 国产精品入口夜色视频大尺度| 久久久久久成人精品| 欧美一级电影免费在线观看| 亚洲free性xxxx护士hd| 亚洲成人教育av| 欧美日本黄视频| 热99精品只有里视频精品| 国产精品午夜视频| 国产999在线观看| 美女啪啪无遮挡免费久久网站| 欧美日韩aaaa| 亚洲国产一区二区三区四区| 日韩欧美成人免费视频| 精品网站999www| 91国产精品电影| 国产精品久久电影观看| 尤物yw午夜国产精品视频| 日韩中文综合网| 欧美裸体视频网站| 国产日韩精品视频| 欧美人与性动交| 91精品视频免费观看| 性日韩欧美在线视频| 成人xxxx视频| 国产欧美日韩专区发布| 亚洲女人天堂色在线7777| 欧美激情亚洲精品| 欧美精品精品精品精品免费| 91黑丝在线观看| 国产精品久久久久影院日本| 国产一区二区三区四区福利| 51午夜精品视频| 91精品国产精品| 久久久久久久久国产| 色99之美女主播在线视频| 日韩欧美亚洲一二三区| 日韩不卡在线观看| 久久亚洲精品一区二区| 国产精品丝袜白浆摸在线| 91极品视频在线| 国产午夜精品一区二区三区| 精品久久久国产精品999| 亚洲资源在线看| 国产精品美女在线| 亚洲无亚洲人成网站77777| 92福利视频午夜1000合集在线观看| 久久久国产成人精品| 色偷偷9999www| 激情成人在线视频| 久久精品国产一区| 日韩精品在线视频| 亚洲精品wwww| 亚洲午夜色婷婷在线| 日韩毛片中文字幕| 国产精品毛片a∨一区二区三区|国| 欧美亚洲第一区| 亚洲欧美制服综合另类| 色偷偷91综合久久噜噜| 欧美亚洲成人xxx| 在线观看视频亚洲| 国产精品久久久999| 日韩国产在线播放| 伊人久久久久久久久久| 在线国产精品视频| 亲爱的老师9免费观看全集电视剧| 亚洲国产成人精品一区二区| 国产亚洲精品久久久久久777| 免费99精品国产自在在线| 91色琪琪电影亚洲精品久久| 久久久久久一区二区三区| 国产日韩欧美在线看| 欧美精品九九久久| 日韩av男人的天堂| 成人欧美在线观看| 丝袜美腿精品国产二区| 国内精品在线一区| 国内精品久久久久久影视8| 在线看福利67194| 国产精品成人av在线| 日韩高清人体午夜| 69久久夜色精品国产69乱青草| 色综合男人天堂| 亚洲成人久久网| 亚洲激情第一页| 日韩在线视频网站| 亚洲第一网中文字幕| 欧美精品国产精品日韩精品| 精品一区二区三区四区| 亚洲日韩中文字幕在线播放| 91精品免费看| 色吧影院999| 91手机视频在线观看| 国产欧美亚洲精品| 国产精品丝袜久久久久久不卡| 国产精品自产拍在线观看中文| 青青草国产精品一区二区| 蜜月aⅴ免费一区二区三区| 色噜噜狠狠狠综合曰曰曰88av| 欧美激情精品久久久久久| 亚洲午夜久久久影院| 亚洲精品之草原avav久久| 一区二区三区日韩在线| 久久天天躁狠狠躁夜夜躁2014| 精品人伦一区二区三区蜜桃免费| 成人免费大片黄在线播放| 久久久久一本一区二区青青蜜月| 亚洲va久久久噜噜噜| 国产精彩精品视频| 亚洲色图综合久久| 国产视频精品在线| 久久精品久久精品亚洲人| 成人免费观看网址| 亚洲女同精品视频| 亚洲欧洲成视频免费观看| 91老司机精品视频| 国产成人一区二区在线| 色哟哟亚洲精品一区二区| 91av视频在线观看| 在线精品视频视频中文字幕| 亚洲女成人图区| 欧美性猛交xxxx富婆弯腰| 日本免费一区二区三区视频观看| 国产91在线播放| 久久国产精品免费视频| 日本久久久a级免费| 日韩中文字幕视频| 粉嫩老牛aⅴ一区二区三区| 久久久久久久爱| 国产91成人video| 亚洲精品按摩视频| 欧美极品欧美精品欧美视频| 国产成人精品a视频一区www| 欧美激情乱人伦一区| 一本色道久久综合亚洲精品小说| 成人久久久久爱| 欧美有码在线观看视频| 一区二区三区精品99久久| 久久视频在线免费观看| 91啪国产在线| 日本精品va在线观看| 亚洲天堂色网站| 亚洲成色777777女色窝| 91性高湖久久久久久久久_久久99| 国产精品电影久久久久电影网| 精品中文视频在线| 日本精品久久电影| 亚洲美女性视频| 538国产精品视频一区二区| 中国china体内裑精亚洲片| 色婷婷av一区二区三区久久| 欧美视频在线观看 亚洲欧|