57

newオブジェクトのメモリがすでにある場合、を使用せずにコンストラクタを明示的に呼び出すことはできますか?

class Object1{
    char *str;
public:
    Object1(char*str1){
        str=strdup(str1);
        puts("ctor");
        puts(str);
    }
    ~Object1(){
        puts("dtor");
        puts(str);
        free(str);
    }
};

Object1 ooo[2] = {
     Object1("I'm the first object"), Object1("I'm the 2nd")
};

do_smth_useful(ooo);
ooo[0].~Object1(); // call destructor
ooo[0].Object1("I'm the 3rd object in place of first"); // ???? - reuse memory
4

9 に答える 9

83

ある種。new配置を使用して、すでに割り当てられているメモリを使用してコンストラクターを実行できます。

 #include <new>

 Object1 ooo[2] = {Object1("I'm the first object"), Object1("I'm the 2nd")};
 do_smth_useful(ooo);
 ooo[0].~Object1(); // call destructor

 new (&ooo[0]) Object1("I'm the 3rd object in place of first");

したがって、引き続きnewキーワードを使用していますが、メモリの割り当ては行われません。

于 2010-03-22T17:45:26.357 に答える
17

新しい配置を探していると思います。C ++ FAQ Liteには、これを行う方法の概要が記載されています。このエントリからいくつかの重要な落とし穴があります:

  1. #include <new>配置の新しい構文を使用することになっています。
  2. メモリバッファは、作成するオブジェクトに合わせて適切に調整する必要があります。
  3. デストラクタを手動で呼び出すのはあなたの仕事です。
于 2010-03-22T17:47:35.523 に答える
17

建設と破壊の両方でそれがどのように行われるかについてのいくつかのコードをお見せしましょう

#include <new>

// Let's create some memory where we will construct the object.
MyObject* obj = (MyObject*)malloc(sizeof(MyObject));

// Let's construct the object using the placement new
new(obj) MyObject();

// Let's destruct it now
obj->~MyObject();

// Let's release the memory we used before
free(obj);
obj = 0;

上記の要約が物事をより明確にすることを願っています。

于 2010-03-22T18:06:13.157 に答える
6

文字通り、いいえ、「new」キーワードなしではそれを行うことはできません。実際にメモリを割り当てずにコンストラクタを呼び出すために「new」キーワードを使用する方法については、配置新規に関するすべての回答を参照してください。

于 2010-03-22T17:57:27.980 に答える
2

はい、独自に割り当てられたバッファーがある場合は、新しい配置を使用します。ブライアンボンディは、関連する質問でここで良い応答をしています:

「新しい配置」にはどのような用途がありますか?

于 2010-03-22T17:47:32.777 に答える
1

デストラクタを呼び出すことはできますが、メモリは再利用されず、呼び出しは関数呼び出しと同等になります。デストラクタの下では、仕様に基づいてオブジェクトを破棄することと、メモリを再利用することの2つのことを行うことを覚えておく必要があります。とにかくスタックに割り当てられたオブジェクトに対してdtorが呼び出されるため、2回呼び出すと、未定義の動作が発生する可能性があります。

于 2010-03-22T17:47:27.130 に答える
1

はい、プレースメントnewを使用します-上記のように、オブジェクトをコピーすることを意味する場合でも、ストレージを管理するために2番目のファクトリクラスを用意することを検討してください。memcpy()は、一般的に小さなオブジェクトには安価です。

于 2010-03-22T17:53:44.463 に答える
0

次のテンプレートを使用できます

template <typename T, typename... Args>
inline void InitClass(T &t, Args... args)
{
    t.~T();
    new (&t) T(args...);
}

利用方法:

struct A
{
   A() {}
   A(int i) : a(i) {}
   int a;
} my_value;

InitClass(my_value);
InitClass(my_value, 5);
于 2019-03-26T02:37:45.593 に答える
-2

コメントに基づくと、これはMicrosoftC++コンパイラでのみ機能します

非常に簡単に、なしでnew

    imguistate = (int *)malloc(ImGui::GetInternalStateSize());
    memset(imguistate, 0, ImGui::GetInternalStateSize());
    ((ImGuiState *)imguistate)->ImGuiState::ImGuiState();

これはどのクラスでも機能します。

class SomeClass {
public:
    SomeClass() {
        printf("Called constructor\n");
    }
};

int main () {
    SomeClass *someclass = new SomeClass;
    someclass->SomeClass::SomeClass(); // call constructor again
}
于 2016-08-05T00:12:57.023 に答える