最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解在C++中顯式默認(rèn)設(shè)置的函數(shù)和已刪除的函數(shù)的方法

 更新時(shí)間:2016年01月19日 17:07:05   投稿:goldensun  
這篇文章主要介紹了在C++中顯式默認(rèn)設(shè)置的函數(shù)和已刪除的函數(shù)的方法,文中講到了C++11標(biāo)準(zhǔn)中的新特性,需要的朋友可以參考下

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

  • 如果顯式聲明了任何構(gòu)造函數(shù),則不會(huì)自動(dòng)生成默認(rèn)構(gòu)造函數(shù)。
  • 如果顯式聲明了虛擬析構(gòu)函數(shù),則不會(huì)自動(dòng)生成默認(rèn)析構(gòu)函數(shù)。
  • 如果顯式聲明了移動(dòng)構(gòu)造函數(shù)或移動(dòng)賦值運(yùn)算符,則:
  1. 不自動(dòng)生成復(fù)制構(gòu)造函數(shù)。
  2. 不自動(dòng)生成復(fù)制賦值運(yùn)算符。
  • 如果顯式聲明了復(fù)制構(gòu)造函數(shù)、復(fù)制賦值運(yùn)算符、移動(dòng)構(gòu)造函數(shù)、移動(dòng)賦值運(yùn)算符或析構(gòu)函數(shù),則:
  1. 不自動(dòng)生成移動(dòng)構(gòu)造函數(shù)。
  2. 不自動(dòng)生成移動(dòng)賦值運(yùn)算符。

注意

此外,C++11 標(biāo)準(zhǔn)指定將以下附加規(guī)則:

  • 如果顯式聲明了復(fù)制構(gòu)造函數(shù)或析構(gòu)函數(shù),則棄用復(fù)制賦值運(yùn)算符的自動(dòng)生成。
  • 如果顯式聲明了復(fù)制賦值運(yùn)算符或析構(gòu)函數(shù),則棄用復(fù)制構(gòu)造函數(shù)的自動(dòng)生成。
  • 在這兩種情況下,Visual Studio 將繼續(xù)隱式自動(dòng)生成所需的函數(shù)且不發(fā)出警告。

這些規(guī)則的結(jié)果也可能泄漏到對(duì)象層次結(jié)構(gòu)中。例如,如果基類因某種原因無(wú)法擁有可從派生類調(diào)用的默認(rèn)構(gòu)造函數(shù) - 也就是說(shuō),一個(gè)不采用任何參數(shù)的 public 或 protected 構(gòu)造函數(shù) - 那么從基類派生的類將無(wú)法自動(dòng)生成它自己的默認(rèn)構(gòu)造函數(shù)。

這些規(guī)則可能會(huì)使本應(yīng)直接的內(nèi)容、用戶定義類型和常見(jiàn) C++ 慣例的實(shí)現(xiàn)變得復(fù)雜 — 例如,通過(guò)以私有方式復(fù)制構(gòu)造函數(shù)和復(fù)制賦值運(yùn)算符,而不定義它們,使用戶定義類型不可復(fù)制。

struct noncopyable
{
 noncopyable() {};

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

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

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

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

struct widget
{
 widget()=default;

 inline widget& operator=(const widget&);
};


inline widget& widget::operator=(const widget&) =default;

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

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

刪除普通成員函數(shù)或非成員函數(shù)可阻止有問(wèn)題的類型提升導(dǎo)致調(diào)用意外函數(shù)。這可發(fā)揮作用的原因是,已刪除的函數(shù)仍參與重載決策,并提供比提升類型之后可能調(diào)用的函數(shù)更好的匹配。函數(shù)調(diào)用將解析為更具體的但可刪除的函數(shù),并會(huì)導(dǎo)致編譯器錯(cuò)誤。

// 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; }

請(qǐng)注意,在前面的示例中,使用 call_with_true_double_only 參數(shù)調(diào)用 float 將導(dǎo)致編譯器錯(cuò)誤,但使用 call_with_true_double_only 參數(shù)調(diào)用 int 不會(huì)導(dǎo)致編譯器錯(cuò)誤;在 int 示例中,此參數(shù)將從 int 提升到 double,并成功調(diào)用函數(shù)的 double 版本,即使這可能并不是預(yù)期目的。若要確保使用非雙精度參數(shù)對(duì)此函數(shù)進(jìn)行的任何調(diào)用均會(huì)導(dǎo)致編譯器錯(cuò)誤,您可以聲明已刪除的函數(shù)的模板版本。

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.

相關(guān)文章

最新評(píng)論

云龙县| 利辛县| 新余市| 托克逊县| 舟曲县| 黄山市| 东台市| 米易县| 高州市| 宣汉县| 虞城县| 龙江县| 香港 | 阿鲁科尔沁旗| 喀喇| 安陆市| 珠海市| 台东市| 新化县| 阜宁县| 连山| 黄平县| 柳林县| 象山县| 新干县| 喜德县| 萨嘎县| 海原县| 安图县| 东至县| 墨江| 灌云县| 奉贤区| 漳浦县| 崇仁县| 商河县| 万盛区| 巢湖市| 五寨县| 石家庄市| 云安县|