Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的构造函数和析构函数_C_Pointers_Function Pointers - Fatal编程技术网

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

C语言中的构造函数和析构函数,c,pointers,function-pointers,C,Pointers,Function Pointers,我在读a.T.Schreiner的《OOC》一书,我被困在下面这段代码里: 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 stru

我在读a.T.Schreiner的《OOC》一书,我被困在下面这段代码里:

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 String
const void*class
是如何按照书中所说的
new
函数初始化的

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

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


  • p
    既不是
    struct String
    也不是
    struct Class
    。这是一个指针。它指向一块内存。如何解释这种记忆是一个有趣的问题

    假设我们传递实现字符串的
    struct类
    对象的地址,第一个
    calloc
    调用将分配一块大小为
    struct string
    的内存。因此,假设
    p
    是指向
    struct String
    的指针是完全合理的

    new
    函数对
    struct String
    或任何其他“类”知之甚少。实际上几乎没有什么,除了这样一个事实:任何此类
    struct
    的第一个元素都是指向
    struct类的指针。由于指向任何
    struct
    的指针与指向其第一个元素(模类型)的指针相同,这使得
    p
    也成为指向
    struct类的指针。所以这一行:

    *(const struct Class **)p = class;
    
    p
    指向的结构类指针指定适当的值

    现在这条线

    p = class->ctor(p, &ap); 
    
    调用构造函数,像在任何OO环境中一样向其传递“self”指针。它还将构造函数的结果再次分配给
    p
    ,可能是因为ctor可以(但不必)重新分配对象


    总而言之:
    p
    是指向
    struct String
    的指针,
    new
    将其解释为指向
    struct String
    的第一个元素的指针,该元素必须是指向
    struct Class
    的指针实际上你是对的,但我已经为此投入了2天的时间。所以对我来说知道这一点很重要。这是用一个人的前额把一个方形的钉子塞进一个圆孔里。只要说不。我有一个问题,就是想知道事情是如何运作的,我认为这至少对我有好处。你的第二点,
    class
    String
    的第一个成员是可以的,但是在
    new
    函数中
    class
    是一个用
    const struct class
    声明的变量。所以,如果你说,当你把p转换成一个
    类**
    并写入它时,你是在写入它的
    字段。`是完全错误的。我看不出我是怎么错的
    p
    指向一个字节长的内存块
    sizeof(String)
    ,可以安全地假设它将被当作指向一个
    String
    (实际上,ctor就是这样做的)。所以OP正在将一个
    字符串*
    投射到一个
    类**
    并编写他的类指针指向它。你是对的,但是你的答案需要一点解释,你的答案也给了我一些提示来理解这个难题。你可以说
    new
    中的
    class
    struct class
    的一个变量,但是
    p
    被分配给
    struct String
    的内存,之后在
    *(const struct class**)p=class
    中,我们分配
    String
    创建的
    struct class
    的地址。这就是
    struct String
    class
    是如何初始化的。