2

我已经在 OOC 上浏览了这个 pdf 的前几章:http ://www.planetpdf.com/codecuts/pdfs/ooc.pdf

现在我尝试实现一个 String 类。我以前的文件:main.c 和 new2.h。

这是 main.c:

#include "new2.h"
#include <stdio.h>

int main(){

    void * stringObject = new2(String,"a");

    printf((*stringObject).text);
}

这是new2.h(包括空白代码,因为我摆脱了所有东西,但我认为我需要完成这项工作)。

#include <stdarg.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>


struct Class{
    size_t size;
    void * (* ctor)(void * self, va_list * app);
//  void * (* dtor)(void * self);
//  void * (* clone)(const void * self);
//  int (* differ)(const void * self, const void * b);

};

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

};

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;

}

static const struct Class _String ={
    sizeof(struct String),
    String_ctor

};



const void * String =&_String;



void * new2(const void * _class,...)
{
    const struct Class * mClass = _class;
    void * p = calloc(1,mClass->size);

    assert(p);
    *(const struct Class **)p = mClass;

    if(mClass -> ctor)
    {
        va_list ap;

        va_start(ap,_class);
        p=mClass->ctor(p, &ap);
        va_end(ap);
    }

    return p;

}

new2.h 中的所有函数都是从 pdf 链接中逐字逐句获取的。当我尝试使用 gcc 进行编译时,我收到了警告。我正在取消引用一个 void 指针,以及一个我无法在 main.c 中调用字符串文本的错误,因为我的字符串不是联合或结构。

老实说,我发现 new2.h 令人困惑。正如我所说,我从 pdf 中复制了函数。这是我认为会发生的事情:

  1. new2 被调用。参数 String 告诉计算机创建一个指向 Class 结构的指针,并将其指向已经在 new2.h 中创建的 String 结构。
  2. 我们为 String 对象分配了足够的内存。
  3. 我们调用构造函数 (String_ctor),并使用变量参数列表来获取 char 参数,在本例中为“a”。

我的理解很模糊,这段代码无法编译。任何帮助,将不胜感激!

4

1 回答 1

2

为了使此代码编译替换

 void * stringObject

 struct String * stringObject

否则编译器无法确定 .text 字段的地址。

struct String返回方法的一个原因void*是提供继承。只有调用程序知道struct String正在使用哪个子类。

本书中的示例可以保留,void * stringObject因为它们只使用 String 类的“公共”接口,从不进入内部访问其私有成员。

打印字符串的另一种方法是使用将其打印出来的方法扩展类或定义“朋友”函数。

于 2012-06-03T05:19:27.117 回答