3 回答

TA貢獻1797條經驗 獲得超4個贊
當詢問構造函數時,這是一個與析構函數完全不同的問題。
如霍華德指出virtual,如果您的析構函數是,則差異可以忽略不計。但是,如果您的析構函數不是虛擬的,那就完全不一樣了。構造函數也是如此。
= default對特殊的成員函數(默認構造函數,復制/移動構造函數/賦值,析構函數等)使用語法意味著與簡單地做有很大的不同{}。使用后者,該功能將變為“用戶提供”。這改變了一切。
根據C ++ 11的定義,這是一個瑣碎的類:
struct Trivial
{
int foo;
};
如果嘗試默認構造一個,則編譯器將自動生成一個默認構造函數。復制/移動和銷毀也是如此。因為用戶沒有提供任何這些成員函數,所以C ++ 11規范將其視為“瑣碎的”類。因此,這樣做是合法的,例如將其內容memcpy初始化以此類推。
這個:
struct NotTrivial
{
int foo;
NotTrivial() {}
};
顧名思義,這不再是瑣碎的事。它具有用戶提供的默認構造函數。它是否為空無關緊要;就C ++ 11的規則而言,這不能是瑣碎的類型。
這個:
struct Trivial2
{
int foo;
Trivial2() = default;
};
顧名思義,這是一個瑣碎的類型。為什么?因為您告訴編譯器自動生成默認構造函數。因此,構造函數不是“用戶提供的”。因此,該類型被認為是微不足道的,因為它沒有用戶提供的默認構造函數。
= default當添加阻止創建此類函數的成員函數時,該語法主要用于執行諸如復制構造函數/賦值之類的操作。但是它還會觸發編譯器的特殊行為,因此它在默認構造函數/析構函數中也很有用。

TA貢獻1815條經驗 獲得超6個贊
他們都是不平凡的。
它們都具有相同的noexcept規范,具體取決于基礎和成員的noexcept規范。
到目前為止,我檢測到的唯一區別是,如果Widget包含具有不可訪問或刪除的析構函數的基或成員:
struct A
{
private:
~A();
};
class Widget {
A a_;
public:
#if 1
virtual ~Widget() = default;
#else
virtual ~Widget() {}
#endif
};
然后,=default解決方案將編譯,但Widget不會是可破壞的類型。即,如果您嘗試破壞Widget,則會收到編譯時錯誤。但是,如果不這樣做,您就有一個有效的程序。
Otoh,如果您提供用戶提供的析構函數,則無論您是否解構a,事情都不會編譯Widget:
test.cpp:8:7: error: field of type 'A' has private destructor
A a_;
^
test.cpp:4:5: note: declared private here
~A();
^
1 error generated.
- 3 回答
- 0 關注
- 5319 瀏覽
添加回答
舉報