Бьерн Страуструп - Язык программирования С++. Главы 5-8
Страница 23. Объекты класса как члены



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 указывают на независимые от них
 объекты, каждый из которых надо явно размещать и удалять. Кроме
 того, указатель и объект в свободной памяти суммарно занимают
 больше места, чем объект-член.

 
« Предыдущая статья   Следующая статья »