在C ++中绕过构造函数

肯尼斯

我正在尝试使用gcc-avr将C ++用于AVR编程。主要问题是没有可用的libc ++,并且该实现未定义任何new或delete运算符。同样,没有标题可包括,使用new也不是一个选择。

尝试分配新的动态对象时,我很想这样做:

Class* p = reinterpret_cast<Class*>(malloc(sizeof(Class)));
p->Init();

其中,Init()手动初始化所​​有内部变量。但这是否安全甚至可能?

我已经读过C ++中的对象构造有些复杂,但是没有新的或删除的内容,如何初始化动态分配的对象?


扩展以上问题。

使用标准的g ++和new放置,可以假定C ++使用与C相同的简单的内存分配方式(以下代码示例),以两种方式颠覆构造函数。

  1. 使用new放置初始化所有分配的内存。
  2. 直接使用类方法初始化分配的内存。

当然,只有在以下假设成立的情况下,这才成立:

  • 对象的内存布局在编译时是固定的。
  • 内存分配仅与类变量和观察者正常的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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++在构造函数中捕获异常

来自分类Dev

Ruby C ++扩展中的多个构造函数

来自分类Dev

C ++中的直接构造函数调用

来自分类Dev

C ++中的构造函数和复制构造函数行为

来自分类Dev

C ++中的私有构造函数

来自分类Dev

C ++ 11构造函数中的差异(括号)

来自分类Dev

在构造函数C ++中引发异常

来自分类Dev

C ++中的复制构造函数

来自分类Dev

关于C ++中构造函数的奇怪行为

来自分类Dev

在构造函数C ++中打开文件

来自分类Dev

C ++中构造函数的多个声明

来自分类Dev

C ++通过构造函数中的引用传递

来自分类Dev

如何在C ++中“默认构造函数”

来自分类Dev

在C ++中奇怪地使用构造函数

来自分类Dev

C#中的构造函数

来自分类Dev

在Python 2.7中绕过构造函数

来自分类Dev

构造函数中的C ++虚函数

来自分类Dev

C ++:std :: generate在构造函数中

来自分类Dev

构造函数中的C ++封装和引用

来自分类Dev

C#中的类构造函数

来自分类Dev

构造函数中C#记录的JsonProperty

来自分类Dev

在C ++中返回时复制构造函数

来自分类Dev

C ++中的Promotion构造函数

来自分类Dev

了解C ++中的构造函数

来自分类Dev

C ++中的复制构造函数

来自分类Dev

构造函数中的错误-C ++

来自分类Dev

在Python 2.7中绕过构造函数

来自分类Dev

构造函数中的C ++虚函数

来自分类Dev

C ++,静态对象构造函数中的异常会绕过先前静态对象的析构函数