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

标签 c pointers function-pointers

我正在阅读 A.T. 的一本 OOC 书。 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");
}

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

另外,我想知道 struct Stringconst void *class 是如何像书上说的那样被 new 函数初始化的。

最佳答案

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

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

关于C中的构造函数和析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23591027/

相关文章:

c++ - C++ vtables中的双重间接

c++ - "void *(*)(void *)"在 C++ 中是什么意思?

c - Socketpair 仅打印 stdin 中的第一行

c - 在这种情况下 'character set' 是什么?

c++ - 如何实现共享缓冲区?

c - 在指针递增时没有得到预期的结果

c++ - 为什么要在 C++ 中使用指向成员方法的函数指针?

c - Makefile:管理多个包含路径

c - 如何在Flex中定义 bool 值(二)

C++ 指向 const 的指针