5.5.4 Объекты Класса как Члены
5.5.4 Объекты Класса как Члены
Рассмотрим
class classdef (* table members; int no_of_members; // ... classdef(int size); ~classdef(); *);
Очевидное намерение состоит в том, что classdef должен содержать таблицу длиной size из членов members, а сложность – в том, как сделать так, чтобы конструктор table::table() вызывался с параметром size. Это делается так:
classdef::classdef(int size) : members(size) (* no_of_members = size; // ... *)
Параметры для конструктора члена (здесь это table::table ()) помещаются в определение (не в описание) конструктора класса, вмещающего его (здесь это classdef::classdef()). Поле этого конструктор члена вызывается перед телом конструктра, задающего его список параметров.
Если есть еще члены, которым нужны списки параметров для конструкторов, их можно задать аналогично. Например:
class classdef (* table members; table friends; int no_of_members; // ... classdef(int size); ~classdef(); *);
Список параметров для членов разделяется запятыми (а не двоеточиями), и список инициализаторов для членов может представляться в произвольном порядке:
classdef::classdef(int size)
: friends(size), members(size) (* no_of_members = size; // ... *)
Порядок, в котором вызываются конструкторы, неопределен, поэтому не рекомендуется делать списки параметров с побочными эффектами:
classdef::classdef(int size) : friends(size=size/2), members(size); // дурной стиль (* no_of_members = size; // ... *)
Если конструктору для члена не нужно ни одного парамера, то никакого списка параметров задавать не надо. Например, поскольку table::table был определен с параметром по умолчнию 15, следующая запись является правильной:
classdef::classdef(int size) : members(size) (* no_of_members = size; // ... *)
и размер size таблицы friends будет равен 15.
Когда объект класса, содержащий объект класса, (напрмер, classdef) уничтожается, первым выполняется тело собтвенного деструктора объекта, а затем выполняются деструкторы членов.
Рассмотрим традиционную альтернативу тому, чтобы иметь объекты класса как члены, – иметь члены указатели и инициалзировать их в конструкторе:
class classdef (* table* members; table* friends; int no_of_members; // ... classdef(int size); ~classdef(); *);
classdef::classdef(int size) (* members = new table(size); friends = new table; // размер таблицы по умолчанию no_of_members = size; // ... *)
Так как таблицы создавались с помощью new, они должны уничтожаться с помощью delete:
classdef::~classdef() (* // ... delete members; delete friends; *)
Раздельно создаваемые объекты вроде этих могут оказаться полезными, но учтите, что members и friends указывают на одельные объекты, что требует для каждого из них действие по выделению памяти и ее освобождению. Кроме того, указатель плюс объект в свободной памяти занимают больше места, чем объект член.