placement newの使い方

2024年からは、まとまってようといなかろうと積極的に記事にすることにしたので、しょうもない記事を書いてみます。

今回はC++のplacement newです。

C++だとnew演算子をオーバーロードできたり、allocatorを自作出来たり自由度が高いのですが、placement newを使うと、オブジェクトの再初期化ができます。

#include <iostream>
#include <new>
using namespace std;
struct hoge {
    int a;
    hoge(int a):a(a) {cout << "constructing... " << this << endl;}
    ~hoge() {cout << "destructing... " << this << endl;}
    void print() {cout << "a=" << a << endl;}
};
int main() {
    hoge a(1);
    a.print();
    a.~hoge(); // デストラクタを自分で呼び出す
    new (&a)hoge(2); // これが placement new
    a.print();
    return 0;
}

動かすと

constructing... 0x7ffcd6130614
a=1
destructing... 0x7ffcd6130614
constructing... 0x7ffcd6130614
a=2
destructing... 0x7ffcd6130614

こんな感じでmain関数内でローカル定義されているaオブジェクトが、デストラクタを呼んだ後同じメモリを使ってコンストラクタが再度呼ばれて最初期化されています。

placement newは指定されたアドレスにコンストラクタで指定されたオブジェクトを配置します。普通のnew演算子は通常heapから取得したアドレスにコンストラクタで指定されたオブジェクトを配置しますが、そのアドレスを指定できるということです。こちらから指定するので、場所はheapでなくてもよく、delete演算子も使えません。

詳細は以下をご覧ください。

https://ja.cppreference.com/w/cpp/language/new

未分類C++

Posted by first_user