这个问题是针对嵌入式系统的!
我具有以下用于初始化对象的选项:
Object* o = new Object(arg);
这会将对象放入堆中并返回指向它的指针。我不想在嵌入式软件中使用动态分配。
Object o = Object(arg);
这将在堆栈中创建一个新对象,然后将其复制到对象o
中,然后将其删除。如果对象足够大以适合RAM而不适合堆栈,则可能导致堆栈溢出。我已经看到这种情况在关闭优化的情况下发生了,我没有探索启用优化的情况是否与此不同。
Object o(arg);
这将创建对象而不进行复制,但是如何再次“初始化” o
?
对于嵌入式,我更喜欢最后一个选项,因为不使用堆,并且堆栈中没有临时对象可以引起堆栈溢出。
但是,由于以下原因,我对如何再次重新初始化对象感到困惑:
o.Object(arg)
不允许。
我可以创建一个名为init(arg)的方法并调用
o.init(arg)
与Object::Object(arg)
进行相同的初始化,但是我不希望不必使用我需要记住的“非标准”名称创建一个额外的方法。
是否有一种方法可以调用已创建对象的构造函数,以在不进行复制的情况下再次对其进行初始化?
答案 0 :(得分:2)
请考虑在对象的当前内存中使用new放置。这将在当前使用的内存中初始化一个新对象,而不分配新内存。那可能是您的解决方案。例如:
new (&o) Object(args)
尝试一下:
#include <iostream>
class A
{
public:
A(int i)
{
m_i = i;
}
int m_i;
};
int main()
{
int s = 10;
int *ps = new (&s) int(100);
std::cout << *ps;
std::cout << s;
A a(5);
new (&a) A(49);
std::cout << a.m_i;
}
g++ -std=c++98 main.cpp
返回10010049,这是正确的。
答案 1 :(得分:1)
您需要使用placement new并调用下面的对象析构函数示例
A a = A();//init
a.~A();//clear
new (&a) A();//re init
答案 2 :(得分:1)
步骤1.获得一个可以正常工作的编译器(可以识别将对象初始化到位的最明显的机会),并且至少支持C ++ 11。
第2步。对于初始化,请使用:
auto o = Object(arg); // won't copy ever with optimization turned on
如果您需要使用新参数重新分配给构造函数:
o = Object(arg1); // calls move asignment operator
如果您需要用其他对象的值覆盖该值(以后不打算使用该对象,则不打算使用该值:
o = std::move(o1); // o1 is the other Object, afterwards o1 is left in 'valid but undefinded state'
如果这对您不起作用(仍然出现堆栈抖动/没有移动分配运算符等),则您可能应该进行新的放置,像@tomer zeitune建议的那样显式调用析构函数:
o.~Object(); // cleanup
new (&o) Object();
需要明确调用析构函数,例如释放对象管理的所有资源。