C中的构造函数和析构函数

Ash*_*wat 6 c pointers function-pointers

我正在读一本书OOC A.T. Schreiner,我在这段代码中停留在以下行:

struct Class {
    size_t size;
    void *(* ctor) (void *self, va_list *app);
};

struct String {
    const void *class;  // must be first
    char *text;
};


void *new(const void *_class, ...) {
    const struct Class *class = _class;     // assign the address of `struct String` class
    void *p = calloc(1, class->size);       // allocate the sizeof(struct String);

    assert(p);
    *(const struct Class **)p = class;      // Force the conversion of p and set the argument `class` as the value of this pointer.
    if(class->ctor) {
        va_list ap;
        va_start(ap, _class);
        p = class->ctor(p, &ap);        // Now what is `p` here, a `struct String` or `struct Class`.
                                        // and if it is `struct Class` then how it convert to `struct String` in `String_ctor` function 
                                        // given below.
        va_end(ap);
    }
    return p;
}


static void *String_ctor(void *_self, va_list *app) {
    struct String *self = _self;        
    const char *text = va_arg(*app, const char *);

    self->text = malloc(strlen(text) + 1);
    assert(self->text);
    strcpy(self->text, text);
    return self;
}


// Initialization
static const struct Class _String  = {
    sizeof(struct String),
    String_ctor
};

const void *String = &_String;



// Call like this:
int main(void) {
 void *a = new(String, "some text");
}
Run Code Online (Sandbox Code Playgroud)

现在,正如您所看到的,在new函数中,以下行p = class->ctor(p, &ap)让我很困惑.您可以看到上述评论.

另外,我想知道如何const void *classstruct String被初始化new功能书上说的.

小智 2

  1. p被分配给其返回值,class->ctor因此void *它是一个 void 指针。查看 的定义,String_ctor您可以看到它返回的self是 a String *,因此在这种情况下,您将得到 a void *,可以安全地转换为 aString *

  2. 这是通过 实现的*(const struct Class **)p = class;。由于class是 的第一个成员String,因此指向 a 的指针String将与其class字段的指针具有相同的地址。因此,当您转换p为 aClass **并写入它时,您正在写入它的class字段。

  • 我不明白我怎么错了。`p` 指向一个 `sizeof(String)` 字节长的内存块,并且可以安全地假设它将像指向 `String` 一样使用(事实上,构造函数就是这样做的)。所以OP将一个`String *`转换为一个`Class **`并将他的类指针写入它。 (2认同)