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

C++ConstructorPlacement New

C++ Problem Overview


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



 

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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.

Solution 3 - C++

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.

Solution 4 - C++

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.

Solution 5 - C++

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

https://stackoverflow.com/questions/222557/cs-placement-new

Solution 6 - C++

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.

Solution 7 - C++

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.

Solution 8 - C++

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

Solution 9 - C++

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
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionosgxView Question on Stackoverflow
Solution 1 - C++unwindView Answer on Stackoverflow
Solution 2 - C++Michael KristofikView Answer on Stackoverflow
Solution 3 - C++CthutuView Answer on Stackoverflow
Solution 4 - C++Ben VoigtView Answer on Stackoverflow
Solution 5 - C++itsmattView Answer on Stackoverflow
Solution 6 - C++vehomzzzView Answer on Stackoverflow
Solution 7 - C++Martin BeckettView Answer on Stackoverflow
Solution 8 - C++user11258054View Answer on Stackoverflow
Solution 9 - C++kungfoomanView Answer on Stackoverflow