C ++,是否可以直接调用构造函数而无需new?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2494471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:40:44  来源:igfitidea点击:

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

c++constructorplacement-new

提问by osgx

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

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

回答by unwind

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

有点。您可以使用placement 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");

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

因此,您仍在使用new关键字,但不会进行内存分配。

回答by Michael Kristofik

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

我认为您正在寻找新的安置。在C ++ FAQ精简版有你如何做一个很好的总结。这篇文章有几个重要的问题:

  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.
  1. 您应该#include <new>使用放置新语法。
  2. 您的内存缓冲区需要与您正在创建的对象正确对齐。
  3. 手动调用析构函数是您的工作。

回答by Cthutu

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.

我希望上面的总结能让事情更清楚。

回答by Ben Voigt

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.

从字面上看,不,没有“new”关键字你就做不到。有关使用“new”关键字调用构造函数而不实际分配内存的方法,请参阅有关放置 new 的所有答案。

回答by itsmatt

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

是的,当您拥有自己分配的缓冲区时,您可以使用placement new。布赖恩·邦迪 (Brian Bondy) 在相关问题中给出了很好的回答:

What uses are there for "placement new"?

“placement new”有什么用?

回答by vehomzzz

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.

你可以调用析构函数,但是内存不会被回收,你的调用就相当于一个函数调用。您必须记住,在析构函数下面做两件事:根据您的规范销毁对象,并回收内存。由于无论如何都会为堆栈上分配的对象调用 dtor ,因此调用它两次可能会导致未定义的行为。

回答by Martin Beckett

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.

是的,使用新的放置 - 如上所述,但您可能会考虑使用第二个工厂类来管理存储,即使这意味着复制对象。memcpy() 对于小对象通常很便宜。

回答by user11258054

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

回答by lama12345

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

根据评论,这仅适用于 Microsoft C++ 编译器

Quite simply, without new:

很简单,没有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
}