C ++標準に従って、コンストラクタとデストラクタを明示的に呼び出すことは安全ですか?

ムスタファゴヌル

一部の開発者は、いくつかの回避策のためにコンストラクタとデストラクタを明示的に呼び出します。それは良い習慣ではありませんが、いくつかのシナリオを実現するために行われているようです。

たとえば、この記事「Beautiful Native Libraries」では、作成者がこの手法を使用しています。

以下のコードでは、最後に、コンストラクターが明示的に呼び出されていることがわかります。

#include <limits>

template <class T>
struct proxy_allocator {
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T *pointer;
    typedef const T *const_pointer;
    typedef T& reference;
    typedef const T &const_reference;
    typedef T value_type;

    template <class U>
    struct rebind {
        typedef proxy_allocator<U> other;
    };

    proxy_allocator() throw() {}
    proxy_allocator(const proxy_allocator &) throw() {}
    template <class U>
    proxy_allocator(const proxy_allocator<U> &) throw() {}
    ~proxy_allocator() throw() {}

    pointer address(reference x) const { return &x; }
    const_pointer address(const_reference x) const { return &x; }

    pointer allocate(size_type s, void const * = 0) {
        return s ? reinterpret_cast<pointer>(yl_malloc(s * sizeof(T))) : 0;
    }

    void deallocate(pointer p, size_type) {
        yl_free(p);
    }

    size_type max_size() const throw() {
        return std::numeric_limits<size_t>::max() / sizeof(T);
    }

    void construct(pointer p, const T& val) {
        new (reinterpret_cast<void *>(p)) T(val);
    }

    void destroy(pointer p) {
        p->~T();
    }

    bool operator==(const proxy_allocator<T> &other) const {
        return true;
    }

    bool operator!=(const proxy_allocator<T> &other) const {
        return false;
    }
};

このようなシナリオでは、コンストラクタとデストラクタを明示的に呼び出す必要がある場合がありますが、標準では、未定義の動作、未指定の動作、実装定義の動作、または明確に定義されているとは何ですか?

Niall

はい、サポートされ、明確に定義されています。安全です。

new (reinterpret_cast<void *>(p)) T(val);

配置の新しい構文呼ばれ、特定のメモリ位置にオブジェクトを構築するために使用されます。これはデフォルトの動作です。投稿されたアロケータで必要なものなど。プレースメントnewが特定のタイプに対してオーバーロードされている場合、Tグローバルプレースメントnewの代わりに呼び出されます。

このような構築されたオブジェクトを破棄する唯一の方法は、デストラクタを明示的に呼び出すこと p->~T();です。

プレースメントの新規で明示的な破棄を使用するには、実装されたコードがオブジェクトの存続期間を制御する必要があります。この場合、コンパイラはほとんど支援を提供しません。したがって、オブジェクトが適切に配置され、十分に割り当てられた場所に構築されることが重要です。それらの使用は、OPやstd::allocatorなどのアロケータでよく見られます

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

コンストラクタからデストラクタを明示的に呼び出すことは、C ++では悪い習慣ですか?

分類Dev

C ++ 11:派生クラスを破棄するために、基本クラスのデストラクタを明示的に呼び出すことはできますか?

分類Dev

C ++デストラクタがクラスメンバーのデストラクタと基本クラスのデストラクタを呼び出さないようにすることは可能ですか?

分類Dev

C ++は、初期化リストの外部で親コンストラクターを明示的に呼び出します

分類Dev

C#の別のクラスのコンストラクターからコンストラクターを呼び出すことはできますか?

分類Dev

クラスにコンストラクターが定義されていない場合でも、C ++のデフォルトのムーブ代入演算子をクラスで呼び出すことはできません

分類Dev

C ++およびJavaでのコンストラクター呼び出しに明示的な型パラメーターが必要なのはなぜですか?

分類Dev

C#コンストラクターはそれ自体を呼び出すことができません

分類Dev

C ++でコピーコンストラクターが呼び出されるのはいつですか?オブジェクトを別のオブジェクトに割り当てるときに呼び出されませんか?

分類Dev

C#、サブスレッドでオブジェクトを削除するときにGCがデストラクタを呼び出さなかった

分類Dev

main()c ++でコンストラクターを呼び出すにはどうすればよいですか?

分類Dev

C ++基本クラス/構造体コンストラクターが派生から暗黙的に呼び出すことができる複数の引数を持つことができないのはなぜですか?

分類Dev

C ++標準のどこに、コピーコンストラクターが削除されたときにデフォルトコンストラクターが生成されないと記載されていますか?

分類Dev

C ++標準では、ベクトル代入関数またはコンストラクターに明示的な要件がありますか?

分類Dev

C ++の多重継承と明示的なコンストラクター呼び出し

分類Dev

Python:クラスAはクラスBとCのインスタンスを作成しますが、BとCはどのようにしてAまたは相互に関数を呼び出すことができますか?

分類Dev

仮想デストラクタをC ++で呼び出すにはどうすればよいですか?

分類Dev

C ++ 17の別のコンストラクターとは異なる引数タイプでコンストラクターを呼び出す

分類Dev

C ++デストラクタは、予期しないときに呼び出されています

分類Dev

C ++共用体は、それに格納されている型と、呼び出すデストラクタをどのように認識しますか?

分類Dev

C ++はどのようにして自動的にデストラクタを呼び出しますか?

分類Dev

C ++はオブジェクトを参照によって関数に渡し、そのコンストラクターが呼び出されます

分類Dev

ビルド後のイベントとしてtlbexpコマンドを呼び出して、Visual Studio 2019 IDEのC#EXEからタイプライブラリをエクスポートするにはどうすればよいですか?

分類Dev

nullptrでdeleteを呼び出すことについてC ++ 17標準は何と言っていますか?

分類Dev

C ++が親のデフォルトコンストラクターを暗黙的に呼び出すのはなぜですか?

分類Dev

C#で、コンストラクターからのみプライベート関数を呼び出せるようにすることは可能ですか?

分類Dev

クラスのポインタのデフォルトコンストラクタをC ++のmapの値として呼び出します

分類Dev

GC_mallocを使用してから、C ++でコンストラクターを呼び出す方法は?

分類Dev

c ++:コンストラクターがここで呼び出されるのはなぜですか

Related 関連記事

  1. 1

    コンストラクタからデストラクタを明示的に呼び出すことは、C ++では悪い習慣ですか?

  2. 2

    C ++ 11:派生クラスを破棄するために、基本クラスのデストラクタを明示的に呼び出すことはできますか?

  3. 3

    C ++デストラクタがクラスメンバーのデストラクタと基本クラスのデストラクタを呼び出さないようにすることは可能ですか?

  4. 4

    C ++は、初期化リストの外部で親コンストラクターを明示的に呼び出します

  5. 5

    C#の別のクラスのコンストラクターからコンストラクターを呼び出すことはできますか?

  6. 6

    クラスにコンストラクターが定義されていない場合でも、C ++のデフォルトのムーブ代入演算子をクラスで呼び出すことはできません

  7. 7

    C ++およびJavaでのコンストラクター呼び出しに明示的な型パラメーターが必要なのはなぜですか?

  8. 8

    C#コンストラクターはそれ自体を呼び出すことができません

  9. 9

    C ++でコピーコンストラクターが呼び出されるのはいつですか?オブジェクトを別のオブジェクトに割り当てるときに呼び出されませんか?

  10. 10

    C#、サブスレッドでオブジェクトを削除するときにGCがデストラクタを呼び出さなかった

  11. 11

    main()c ++でコンストラクターを呼び出すにはどうすればよいですか?

  12. 12

    C ++基本クラス/構造体コンストラクターが派生から暗黙的に呼び出すことができる複数の引数を持つことができないのはなぜですか?

  13. 13

    C ++標準のどこに、コピーコンストラクターが削除されたときにデフォルトコンストラクターが生成されないと記載されていますか?

  14. 14

    C ++標準では、ベクトル代入関数またはコンストラクターに明示的な要件がありますか?

  15. 15

    C ++の多重継承と明示的なコンストラクター呼び出し

  16. 16

    Python:クラスAはクラスBとCのインスタンスを作成しますが、BとCはどのようにしてAまたは相互に関数を呼び出すことができますか?

  17. 17

    仮想デストラクタをC ++で呼び出すにはどうすればよいですか?

  18. 18

    C ++ 17の別のコンストラクターとは異なる引数タイプでコンストラクターを呼び出す

  19. 19

    C ++デストラクタは、予期しないときに呼び出されています

  20. 20

    C ++共用体は、それに格納されている型と、呼び出すデストラクタをどのように認識しますか?

  21. 21

    C ++はどのようにして自動的にデストラクタを呼び出しますか?

  22. 22

    C ++はオブジェクトを参照によって関数に渡し、そのコンストラクターが呼び出されます

  23. 23

    ビルド後のイベントとしてtlbexpコマンドを呼び出して、Visual Studio 2019 IDEのC#EXEからタイプライブラリをエクスポートするにはどうすればよいですか?

  24. 24

    nullptrでdeleteを呼び出すことについてC ++ 17標準は何と言っていますか?

  25. 25

    C ++が親のデフォルトコンストラクターを暗黙的に呼び出すのはなぜですか?

  26. 26

    C#で、コンストラクターからのみプライベート関数を呼び出せるようにすることは可能ですか?

  27. 27

    クラスのポインタのデフォルトコンストラクタをC ++のmapの値として呼び出します

  28. 28

    GC_mallocを使用してから、C ++でコンストラクターを呼び出す方法は?

  29. 29

    c ++:コンストラクターがここで呼び出されるのはなぜですか

ホットタグ

アーカイブ