我正在尝试使用gcc-avr将C ++用于AVR编程。主要问题是没有可用的libc ++,并且该实现未定义任何new或delete运算符。同样,没有标题可包括,使用new也不是一个选择。
尝试分配新的动态对象时,我很想这样做:
Class* p = reinterpret_cast<Class*>(malloc(sizeof(Class)));
p->Init();
其中,Init()手动初始化所有内部变量。但这是否安全甚至可能?
我已经读过C ++中的对象构造有些复杂,但是没有新的或删除的内容,如何初始化动态分配的对象?
扩展以上问题。
使用标准的g ++和new放置,可以假定C ++使用与C相同的简单的内存分配方式(以下代码示例),以两种方式颠覆构造函数。
当然,只有在以下假设成立的情况下,这才成立:
如果上述成立,我是否可以不仅仅使用malloc分配内存并使用reinterpret_cast转换为正确的类并手动对其进行初始化?当然,这既是不可移植的,又是hack-ish的,但是我看到的唯一另一种方法是解决该问题,并且根本不使用动态分配的内存。
例子:
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
如果您所谓的C ++编译器不支持operator new
,则您应该能够在类中或作为全局定义简单地提供自己的。这是一篇讨论的文章中operator new
的一个简单文章,稍作修改(在其他许多地方也可以找到):
void* operator new(size_t sz) {
void* mem = malloc(sz);
if (mem)
return mem;
else
throw std::bad_alloc();
}
void operator delete(void* ptr) {
free(ptr);
}
operator new
也可以在此处找到更详细的讨论,尤其是针对类特定的定义。
从注释中看来,给定这样的定义,您的编译器便会愉快地支持标准的堆上对象创建,如下所示:
auto a = std::make_shared<A>();
A *pa = new A{};
使用问题Init
代码片段中显示的方法的问题是,要使它能够正确地与继承(尤其是多重继承或虚拟继承)一起使用,至少在对象构造期间可能抛出异常时,可能会很痛苦。C ++语言有详尽的规则,以确保在这种情况下构造函数会发生有用且可预测的事情。用普通函数复制它可能很快就会变得棘手。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句