The website "dmilvdv.narod.ru." is not registered with uCoz.
If you are absolutely sure your website must be here,
please contact our Support Team.
If you were searching for something on the Internet and ended up here, try again:

About uCoz web-service

Community

Legal information

12.3 Заполнение объектов — geto()

12.3 Заполнение объектов — geto()

Предыдущая  Содержание  Следующая V*D*V

geto() является методом Object, который считывает информацию по указателю FILE и заполняет ей объект. geto() применяется к неинициализированному объекту; поэтому его работа весьма схожа с работой конструктора, такого как ctor(). Однако, ctor() берёт информацию для нового объекта из списка аргументов; geto() читает её из входного потока.

 

Object.d

 

% Class Object {

        ...

%-

:   void * geto (_self, FILE * fp); // создание из файла

 

Пустой тэг определяется предваряющим двоеточием, потому что для инициализированного объекта нет смысла, чтобы метод respondTo возвращал метод geto.

 

Symbol.dc

 

% Var geto {

    struct Var * self = super_geto(Var(), _self, fp);

 

    if (fscanf(fp, "\tvalue %lg\n", & self -> value) != 1)

        assert(0);

    return self;

}

 

Var_geto() предоставляет позаботиться об информации инициализации методам суперкласса и просто читает обратно то, что записано Var_puto(). Обычно для fprintf() в методе puto и для fscanf() в методе geto могут быть определены одинаковые форматы . Однако, значения с плавающей точкой показывают незначительную проблему в ANSI-C: fprintf() для преобразования double использует %g, а fscanf() для обратного преобразования требует %lg . Строки обычно должны размещаться в динамической памяти:

 

% Symbol geto {

    struct Symbol * self = super_geto(Symbol(), _self, fp);

    char buf [BUFSIZ];

 

    if (fscanf(fp, "\tname %s\n\tlex %d\n",

                            buf, & self -> lex) != 2)

        assert(0);

    self -> name = malloc(strlen(buf) + 1);

    assert(self -> name);

    strcpy((char *) self -> name, buf);

    return self;

}

 

Обычно geto() читает в точности то, что записал соответствующий puto(), и точно так же, как конструкторы, оба метода вызывают методы своих суперклассов, восходящих обратно к Object. Однако, есть одно очень важное отличие: мы видели, что Object_puto() пишет имя класса, сопровождаемое адресом:

 

Var at 0x50ecb18        Object

name x                  Symbol

lex 118

value 1                 Var

 

Object_geto() является первым методом, который заполняет объект Var при чтении входных данных. Имя класса Var, записанное puto(), должно быть прочитано и использовано для выделения памяти объекту Var до того, как для заполнения объекта будет вызван метод geto(), то есть Object_geto() начинает чтение сразу после имени класса:

 

% Object geto {

    void * dummy;

%casts

    if (fscanf(fp, " at %p\n", & dummy) != 1)

        assert(0);

    return self;

}

 

Это единственное место, где методы geto и puto не соответствуют друг другу. Переменная dummy необходима: можно было бы избежать её использования с помощью элемента формата %*p, но тогда нельзя было бы обнаружить, действительно ли адрес был частью входных данных.

 

Предыдущая  Содержание  Следующая