[解決済み】デフォルトのコンストラクタとデストラクタの「=default」は「{}」とどう違うのですか?
質問
当初はデストラクタについてのみの質問として投稿しましたが、今回、デフォルトコンストラクタについての考察を追加します。 以下は元の質問です。
自分のクラスに仮想のデストラクタを与えたいが、それは それ以外はコンパイラが生成するものと同じです。
=default
:class Widget { public: virtual ~Widget() = default; };
しかし、より少ないタイプ数で同じ効果を得るには、次のようにします。 空の定義
class Widget { public: virtual ~Widget() {} };
この2つの定義が異なる動作をする方法はあるのでしょうか?
この質問に対して投稿された返信を見ると、デフォルトのコンストラクタの状況も似ているようです。 とquot.の間にほとんど意味の違いがないことを考えると、quot.quot;
=default
と、"
{}
デストラクタの場合は "ですが、デフォルトのコンストラクタの場合も同様に、これらのオプションにほとんど意味の違いはないのでしょうか? つまり、ある型を作成し、その型のオブジェクトが生成も破壊もされると仮定した場合、なぜ次のように記述したいのでしょうか。
Widget() = default;
ではなく
Widget() {}
?
この質問を最初に投稿した後に拡張することは、SOのルールに違反しているとしたら申し訳ありません。 デフォルトのコンストラクタのためにほとんど同じ質問を投稿することは、あまり望ましくない選択肢であると感じました。
どのように解決するのですか?
これは、コンストラクタとデストラクタについて尋ねる場合、全く異なる質問です。
もし、デストラクタが
virtual
であれば、その差はごくわずかです。
ハワードが指摘したように
. しかし、もしあなたのデストラクタが
非仮想
となると、全く別の話になってしまいます。コンストラクターも同様です。
使用方法
= default
構文は、特殊なメンバ関数 (デフォルト コンストラクタ、コピー/移動コンストラクタ/代入、デストラクタなど) に対して、単に
{}
. 後者の場合、その関数はユーザが提供するものになります。そして、それがすべてを変えてしまうのです。
C++11の定義では、これは些細なクラスです。
struct Trivial
{
int foo;
};
デフォルトでコンストラクタを作ろうとすると、コンパイラは自動的にデフォルトのコンストラクタを生成します。コピー/移動、デストラクトも同様です。ユーザーがこれらのメンバ関数を一切提供しなかったため、C++11の仕様では、これを"trivial"クラスとみなしています。したがって、それらの内容をmemcpyして初期化するなど、合法的に行うことができます。
これは
struct NotTrivial
{
int foo;
NotTrivial() {}
};
名前が示すように、これはもはや些細なことではありません。ユーザが用意するデフォルトのコンストラクタを持ちます。空でもかまいません。C++11 の規則に関する限り、これは些細な型ではありえません。
これです。
struct Trivial2
{
int foo;
Trivial2() = default;
};
これも名前が示すように、これはつまらない型です。なぜか?コンパイラにデフォルトのコンストラクタを自動的に生成するように指示したからです。したがって、このコンストラクタはユーザが提供するものではありません(quot; user-provided." user-provided default constructorがないため、この型はトリビアルとみなされます)。
この
= default
構文は、主にコピーコンストラクタやアサイメントのような関数の作成を防ぐメンバ関数を追加するときに使用します。しかし、これはコンパイラが特別な動作をするきっかけにもなるので、デフォルトのコンストラクタやデストラクタでも有用です。
関連
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] C++で、あるコンストラクタを別のコンストラクタから呼び出す(コンストラクタ・チェイニングを行う)ことは可能ですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] C++のstructとclassの違いは何ですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】デストラクタで例外を投げてはいけない場合、その中のエラーはどのように処理するのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] C++11の新しい構文「= default」について
-
[解決済み】仮想関数と純粋仮想関数の違い【重複あり