5.5.4 Объекты класса как члены.

   


Назад  |  Вперёд

Рассмотрим пример:

           class classdef {
              table members;
              int no_of_members;
              // ...
              classdef(int size);
              ~classdef();
           };

Цель этого определения, очевидно, в том, чтобы classdef содержал член, являющийся таблицей размером size, но есть сложность: надо обеспечить вызов конструктора 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)
           {
             // ...
           }

Конструкторы вызываются в том порядке, в котором они заданы в описании класса.

Подобные описания конструкторов существенны для типов, инициализация и присваивание которых отличны друг от друга, иными словами, для объектов, являющихся членами класса с конструктором, для постоянных членов или для членов типа ссылки. Однако, как показывает член no_of_members из приведенного примера, такие описания конструкторов можно использовать для членов любого типа.

Если конструктору члена не требуется параметров, то и не нужно задавать никаких списков параметров. Так, поскольку конструктор table::table() был определен со стандартным значением параметра, равным 15, достаточно такого определения:

           classdef::classdef(int size)
               : members(size), no_of_members(size)
           {
              // ...
           }

Тогда размер таблицы friends будет равен 15.

Если уничтожается объект класса, который сам содержит объекты класса (например, classdef), то вначале выполняется тело деструктора объемлющего класса, а затем деструкторы членов в порядке, обратном их описанию.

Рассмотрим вместо вхождения объектов класса в качестве членов традиционное альтернативное ему решение: иметь в классе указатели на члены и инициализировать члены в конструкторе:

           class classdef {
              table* members;
              table* friends;
              int no_of_members;
              // ...
           };

            classdef::classdef(int size)
            {
             members = new table(size);
             friends = new table;  // используется стандартный
                                   // размер table
             no_of_members = size;
             // ...
           }

Поскольку таблицы создавались с помощью операции new, они должны уничтожаться операцией delete:

           classdef::~classdef()
           {
             // ...
             delete members;
             delete friends;
           }

Такие отдельно создаваемые объекты могут оказаться полезными, но учтите, что members и friends указывают на независимые от них объекты, каждый из которых надо явно размещать и удалять. Кроме того, указатель и объект в свободной памяти суммарно занимают больше места, чем объект-член.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.