1. ホーム
  2. c++

C++の自明でないコンストラクタとは何ですか?

2023-10-28 03:24:16

質問

私はこれを読んでいました http://en.wikipedia.org/wiki/C%2B%2B0x#Modification_to_the_definition_of_plain_old_data

つまらないデフォルトコンストラクタ、つまらないコピーコンストラクタ、コピー代入演算子、つまらないデストラクタについて言及されています。何がトリビアルで何がトリビアルでないのでしょうか?

どのように解決するのですか?

簡単に言うと、quot;trivial" 特殊メンバ関数は、文字通り、非常に簡単な方法でその仕事をするメンバ関数を意味します。この単純な方法とは、特殊メンバ関数の種類によって異なることを意味します。

デフォルトのコンストラクタとデストラクタの場合、"trivial" は文字通り "do nothing at all" を意味します。コピーコンストラクタとコピー代入演算子については、"trivial" とは、文字通り "be equivalent to simple raw memory copying" (like copy with ) という意味です。 memcpy ).

コンストラクタを自分で定義すると、何もしなくても非自明とみなされるため、自明なコンストラクタはコンパイラが暗黙的に定義する必要があります。

特殊なメンバ関数が上記の要件を満たすためには、クラスが非常に単純な構造でなければならず、オブジェクトが生成または破壊されるときに隠れた初期化を必要としたり、コピーされるときに隠れた追加の内部操作を必要としたりしてはならないのです。

例えば、クラスが仮想関数を持つ場合、このクラスのオブジェクトが作成されるときに、いくつかの隠された初期化(仮想メソッドテーブルの初期化など)を必要とするので、このクラスのコンストラクタは単純なものとは認められません。

別の例として、クラスが仮想ベースクラスを持つ場合、このクラスの各オブジェクトは、まさに同じオブジェクトの他の部分を指す隠しポインタを含むかもしれません。このような自己参照オブジェクトは、単純な生のメモリコピールーチン ( memcpy ). コピーの隠れポインタを適切に再初期化するために、余分な操作が必要になります。この理由から、このクラスのコピーコンストラクタとコピー代入演算子は、些細なこととして認定されません。

明らかな理由により、この要件は再帰的です。クラスのすべてのサブオブジェクト (ベースと非静的メンバー) はまた、トリビアルなコンストラクタを持たなければなりません。