C++, is it possible to call a constructor directly, without new?

心不动则不痛 提交于 2019-12-17 08:24:42

问题


Can I call constructor explicitly, without using new, if I already have a memory for object?

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

回答1:


Sort of. You can use placement new to run the constructor using already-allocated memory:

 #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");

So, you're still using the new keyword, but no memory allocation takes place.




回答2:


I think you're looking for Placement New. The C++ FAQ Lite has a good summary of how you do this. There are a few important gotchas from this entry:

  1. You're supposed to #include <new> to use the placement new syntax.
  2. Your memory buffer needs to be properly aligned for the object you are creating.
  3. It's your job to manually call the destructor.



回答3:


Let me show you some code on how it can be done, both in construction and destruction

#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;

I hope the above summary makes things clearer.




回答4:


Literally speaking, NO, you can't do it without the "new" keyword. See all the answers about placement new for the way to use the "new" keyword to call the constructor without actually allocating memory.




回答5:


Yes, when you've got your own allocated buffer you use placement new. Brian Bondy has a good response here in a related question:

What uses are there for "placement new"?




回答6:


You can call a destructor, but memory will not be reclaimed, and your call will be equivalent to a function call. You have to remember that underneath the destructor does 2 things: destructs object based on your specification, and reclaims the memory. Since you dtor will be called anyway for an object allocated on the stack, calling it twice may result in an undefined behavior.




回答7:


Yes, using placement new - as above, but you might consider having a second factory class to manage the storage, even if it means copying an object. memcpy() is generally cheap for small objects.




回答8:


You can use the following template

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

usage:

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

InitClass(my_value);
InitClass(my_value, 5);



回答9:


Based on comments, this only works for Microsoft C++ compilers

Quite simply, without new:

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

This works with any class:

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

int main () {
    SomeClass *someclass = new SomeClass;
    someclass->SomeClass::SomeClass(); // call constructor again
}


来源:https://stackoverflow.com/questions/2494471/c-is-it-possible-to-call-a-constructor-directly-without-new

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!