簡體   English   中英

為什么要“默認”復制/移動構造函數或析構函數?

[英]Why would you “default” a copy/move constructor or a destructor?

C ++ 0x允許您將某些函數指定為默認值:

struct A {
  A() = default;          // default ctor
  A(A const&) = default;  // copy ctor
  A(A&&) = default;       // move ctor
  A(Other);               // other ctor

  ~A() = default;         // dtor

  A& operator=(A const&) = default; // copy assignment
  A& operator=(A&&) = default;      // move assignment
};

這些函數的實現與編譯器生成它們的情況相同,這種情況通常在您未聲明自己的情況下在大多數情況下發生。

如果您聲明任何ctor(上述任何其他ctor),則不會生成默認ctor,因此您可能需要將其默認為“將其恢復”。

但是,除非基類或數據成員排除它們,否則類總是有一個副本並移動它們 - 如果它們被排除,則默認實現將不起作用。 一個班級總是有一個dtor。

為什么需要顯式默認復制ctor,移動ctor或析構函數? 無論如何,隱式生成的實現不會做同樣的事情嗎?

您可能需要這樣做以更改其對非公共的訪問權限或控制哪個翻譯單元定義它們。

非公有制

即使這些功能通常是公開的,您可能希望它們在非公開的同時仍然需要默認實現:

struct A {
protected:
  ~A();

private:
  A();
  A(A const&);
  A(A&&);
};

// according to N3092, §8.4.2/2, cannot be non-public and defaulted
// in the class definition
A::~A() = default;
A::A() = default;
A::A(A const&) = default;
A::A(A&&) = default;

此類可以默認構造,復制和移動,但只能由A的方法和朋友進行。這對於可能更嚴格控制構造的工廠非常有用。

受保護的析構函數是基類的公共虛擬/受保護 - 非虛擬指南的后半部分:

准則#4:基類析構函數應該是公共的和虛擬的,或者是受保護的和非虛擬的。

定義控制

此外,默認函數可用於維護穩定的二進制接口,因為您可以控制默認函數的定義位置。 默認並不意味着內聯,因為隱式聲明的版本將是。 (在上面的代碼中,默認函數必須不在標題中或添加了內聯說明符。)

除了功能目的,我發現它有助於清晰起見。 它清楚地表明該結構是默認可構造的(或其他),並且我們正在使用編譯器生成的行為。 記錄代碼的自我越多越好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM