使用 malloc() 初始化 Class

Initialization of Class using malloc()

如果 C++ class 的内存已从 C malloc 保留,应如何使用?

我正在使用 C 库 (lua),我需要向其公开 C++ class,在这种情况下,为了垃圾收集这些保留 space, lua 保留内存。

一个更简单的类似场景如下:

#include <string>

class Clase{
private:
    std::string valor;
public:
    Clase(){}
    Clase(const std::string & valor) : valor(valor){}
    const std::string & get() const { return this->valor; }
    void set(const std::string & valor){ this->valor = valor;}
    ~Clase(){}
};

typedef struct
{
    Clase cls;
}Estructura;

int main(int argc, char ** argv)
{
    Estructura * est = (Estructura *) malloc(sizeof(Estructura));

    est->cls.set("Hola");   // First attempt

    Clase myCls;   // Second attempt
    est->cls = myCls;

    return 0;
}

我了解并检查过,使用 malloc 时 class 构造函数不会被调用;这是预期的,因此不能使用无效实例(Class 内的字符串)调用复制(赋值)运算符。我怀疑第二次尝试在同一点失败,在 Class 实例中复制字符串时。

所以:

在 Estructura 中使用 Clase 指针,效果很好,这是最好的解决方案吗?

作为奖励,在 lua 垃圾回收时删除实例的最佳方法是什么?使用 __gc 元方法还是更好的方法?

使用 malloc 而不是 new 有点奇怪,但这是可能的。您需要使用 placement new:

void *memory = malloc(sizeof(Estructura));

Estructura *est = new(memory)Estructura;

完成对象后,您有责任自己调用析构函数:

est->~Estructura();

所有的东西,比如vtables,都会被正确初始化,所以不用担心。尴尬的一点是处理删除,因为您需要在通过 free 释放内存之前销毁对象。 delete 会自动为您执行此操作,但您需要自己执行此操作。