メインコンテンツ

空のデストラクターによって不要なデータ コピーが生じることがあります

ユーザーが宣言した空のデストラクターによって、移動コンストラクターと移動代入演算子の自動生成が回避される

説明

この欠陥は、クラス定義に空の実装または =default 実装を使用したユーザー定義デストラクターが含まれており、移動コンストラクターと移動代入演算子の両方が宣言されていない場合に発生します。次に例を示します。

class aClass
{
public:
    ~aClass() noexcept
     {} // Empty body
};
class bClass
{
public:
    ~bClass() = default;
};
上記デストラクターは、コンパイラ提供バージョンとまったく同じですが、移動操作の自動生成を回避します。その結果、クラス型は移動できません。

空のデストラクターは、以下の場合にフラグが設定されません。

  • デストラクターがプライベートまたは保護されている。

  • デストラクターが最後に宣言されている。

  • デストラクターがバーチャルとして宣言されており、基底クラス デストラクターをオーバーライドしない。

  • デストラクターが基底クラスの純粋なバーチャル デストラクターをオーバーライドする。

  • クラスにトリビアル コピー コンストラクターが含まれている (そのため、コピー操作は移動操作より計算量が少なくなる)。

リスク

このクラスのインスタンスは、移動操作が実行可能な状況で不必要にコピーされる可能性があります。コピー操作は、移動操作よりコストがかかるため、パフォーマンスに影響する可能性があります。

修正方法

次のいずれかの解決策を試します。

  • 可能であれば、空のデストラクターを削除します。クラスにデストラクターが含まれていない場合は、コンパイラがデストラクターを生成します。これは、事実上、明示的に宣言された空のデストラクターです。

    Rule of Zero も参照してください。

  • デストラクターを削除できない場合は、明示的な移動コンストラクターと移動代入演算子をクラス定義に追加します。=default 構文を使用して、移動コンストラクターと移動代入演算子のコンパイラ定義が使用されることを明示します。

    class aClass
    {
    public:
         ~aClass() noexcept = default;
         aClass(aClass&& ) = default;
         aClass& operator=(aClass&& ) = default;
    };

    Rule of Five も参照してください。

パフォーマンスの改善の程度は、使用しているコンパイラ、ライブラリ実装、環境によって異なる可能性があります。

結果情報

グループ: パフォーマンス
言語: C++
既定値: オフ
コマンド ライン構文: EMPTY_DESTRUCTOR_DEFINED
影響度: Low

バージョン履歴

R2020a で導入