Передача параметров методам

Дополнительный параметр каждого метода, определяющий экземпляр структуры (класса), к которому следует применить этот метод, рекомендуется реализовывать как указатель. Хотя в языке C и допускаются параметры, имеющие тип структуры, передача значения структуры в качестве параметра связана с переписыванием значения этой структуры в автоматическую память соответствующей функции, что не только связано с потерей эффективности, но и семантически неверно, когда структура определяет объект, так как применение метода должно изменить значения соответствующих полей этой структуры (они представляют атрибуты объекта). Пример передачи параметров одному из методов (этот метод входит в список методов, приведённый в комментарии к определению структуры Window):

add_to_selections (shape, self)

struct Window* self;

struct Shape* shape;

 

Размещение объектов в памяти

Объекты, определённые в программе на языке C,могут размещаться в памяти программы (статические глобальные объекты), в стеке (автоматически размещаемые локальные объекты) или в куче (динамические объекты). Время жизни статических объектов – это всё время выполнения программы. Они используются для хранения глобальных переменных и констант, но при объектно-ориентированной разработке программ стараются использовать как можно меньше глобальных объектов, так как они нарушают модульную структуру программы. Глобальные объекты в языке C объявляются на внешнем уровне программного файла, вне составляющих его функций; инициализация таких объектов обычно производится при их порождении во время компиляции программы. Пример объявления статического (глобального) объекта:

static struct Window outer_window = {0.0, 0.0, 8.5, 11.0};

При вызове методов, использующих объявленную глобальную переменную, им следует передавать её адрес (&outer_window).

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

Динамически размещаемые объекты необходимо использовать, когда во время компиляции программы неизвестно их количество. Такие объекты размещаются в куче по запросу (функции malloc или сalloc) во время выполнения программы. Будучи размещённым в памяти динамический объект сохраняется в ней до тех пор, пока не будет явным образом отменён (функция free). Пример функции размещения и инициализации динамического объекта:

struct Window* create_window(xmin, ymin, width, height);

Length xmin, ymin, width, height;

{

struct Window* window;

/*размещение объекта*/

window = (struct Window*)malloc(sizeof(struct Window));

/*инициализация объекта*/

window-> xmin = xmin;

window-> ymin = ymin;

window-> xmax = xmin + width;

window-> ymax = ymin + height;

return window;

};

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

 

Реализация наследования

Наследование в языке C реализуются через указатели. Рассмотрим, например, конкретные подклассы Box и Circle абстрактного класса Shape. На языке C их можно представить следующим образом:

struct Shape

{

struct ShapeClass* class;

Length x;

Length y;

};

struct Box

{

struct BoxClass* class;

Length x;

Length y;

Length width;

Length height;

};

struct Circle

{

struct CircleClass* class;

Length x;

Length y;

Length radius;

};

Указатель на структуры Box или Circle можно передать функции, ожидающей указатель на Shape, так как первые несколько членов структур Box и Circle идентичны первым членам структуры Shape (это позволяет привести тип указателя на структуру Box или Circle привести к типу указателя на структуру Shape).