我正在尝试使用C++进行使用gcc-avr的AVR编程。主要问题是没有libC++可用,并且实现没有定义任何新的或删除操作符。同样,没有包含使用展示位置的标题新不是一个选项。在C++中绕过构造函数
当试图分配我很想只是做这个新的动态对象:
Class* p = reinterpret_cast<Class*>(malloc(sizeof(Class)));
p->Init();
其中的init()手动初始化所有的内部变量。但这是安全的还是可能的?
我读过C++中的对象构造有点复杂,但没有新的或删除如何初始化一个动态分配的对象?
展开上述问题。
使用标准的g ++和placement new,假设C++使用与C一样简单的内存匹配方式(下面的代码示例),可以以两种方式颠覆构造函数。
- 使用placement new来初始化任何分配的内存。
- 直接使用类方法初始化分配的内存。
当然,这仅成立当假设为真:
- 对象的内存布局是固定在编译时。
- 内存分配只涉及类变量和观察者正常的C规则(按声明顺序对齐内存边界分配)。
如果上述问题可以不使用malloc分配内存,并使用reinterpret_cast转换为正确的类并手动初始化它?当然,这既是不可移植的,也是黑客行为,但我能看到的唯一方法是解决问题,而不是动态分配内存。
例子:
Class A {
int i;
long l;
public:
A() : i(1), l(2) {}
int get_i() { return i; }
void set_i(int x) { i = x; }
long get_l() { return l; }
void set_l(long y) { l = y; }
};
Class B {
/* Identical to Class A, except constructor. */
public B() : i(3), l(4) {}
};
int main() {
A* a = (A*) ::operator new(sizeof(A));
B* b = (B*) ::operator new(sizeof(B));
/* Allocating A using B's constructor. */
a = (A*) new (a) B();
cout << a->get_i() << endl; // prints 3
cout << a->get_l() << endl; // prints 4
/* Setting b directly without constructing */
b->set_i(5);
b->set_l(6);
cout << b->get_i() << endl; // prints 5
cout << b->get_l() << endl; // prints 6
我的建议是查看新的实现(例如在libC++中)并将其复制到项目中。 – MikeMB 2015-04-04 20:53:20
'malloc'分配的空间可能无法正确初始化。所以'p-> Init()'可能会导致错误。 – wowofbob 2015-04-04 20:54:43
如果你想要一个C++的方式,你应该跳过'malloc'并且执行'Class * p = :: operator new(sizeof(Class));'。我很确定这不会调用构造函数。但我认为'delete'总是会调用析构函数。 – 2015-04-04 21:02:05