如果我已经有对象的内存,我可以显式调用构造函数而不使用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
答案 0 :(得分:76)
排序。您可以使用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");
因此,您仍在使用new
关键字,但不会进行内存分配。
答案 1 :(得分:15)
我认为您正在寻找Placement New。 C++ FAQ Lite总结了你如何做到这一点。这个条目有一些重要的问题:
#include <new>
使用展示位置新语法。答案 2 :(得分:15)
让我向您展示一些关于如何在构造和破坏方面完成的代码
#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;
我希望上述摘要能让事情更加清晰。
答案 3 :(得分:5)
从字面上讲,不,没有“new”关键字,你就无法做到。有关使用“new”关键字调用构造函数而不实际分配内存的方法,请参阅有关placement new的所有答案。
答案 4 :(得分:2)
是的,当你有自己的分配缓冲区时,你可以使用placement new。 Brian Bondy在一个相关的问题中得到了很好的回应:
答案 5 :(得分:1)
您可以调用析构函数,但不会回收内存,并且您的调用将等同于函数调用。你必须记住,在析构函数下面做了两件事:根据你的规范破坏对象,并回收内存。由于无论如何都要为堆栈上分配的对象调用dtor,因此调用它两次可能会导致未定义的行为。
答案 6 :(得分:1)
是的,使用placement new - 如上所述,但您可能会考虑使用第二个工厂类来管理存储,即使这意味着复制对象。 memcpy()对于小物体来说通常很便宜。
答案 7 :(得分: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);
答案 8 :(得分:-1)
它的新呼叫放置似乎是趋势,所以我尝试提供一种替代方法。不确定是否很好。
pip3
由于所有已添加的函数调用,我对此路径感到怀疑。即使编译器有可能将其优化掉。
有人说构造函数是无名的。那显然不是事实;我认为cpp团队想强调构造和任务之间的区别。如果你问我,那真是愚蠢。
答案 9 :(得分:-2)
根据评论,这仅适用于Microsoft C ++编译器
非常简单,没有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
}