Бьерн Страуструп - Язык программирования С++. Главы 5-7 - Объекты класса как члены
ОГЛАВЛЕНИЕ
5.5.4 Объекты класса как члены
Рассмотрим пример:          class classdef {
             table members;
             int no_of_members;
             // ...
             classdef(int size);
             ~classdef();
          };Цель этого определения, очевидно, в том, чтобы classdef содержал член, являющийся таблицей размером size, но есть сложность: надо обеспечить вызов конструктора table::table() с параметром size. Это можно сделать, например, так:classdef::classdef(int size)Параметр для конструктора члена (т.е. для table::table()) указывается в определении (но не в описании) конструктора класса, содержащего член (т.е. в определении classdef::classdef()). Конструктор для члена будет вызываться до выполнения тела того конструктора, который задает для него список параметров.
:members(size)
{
no_of_members = size;
// ...
}
Аналогично можно задать параметры для конструкторов других членов (если есть еще другие члены):
           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)Тогда размер таблицы friends будет равен 15.
: members(size), no_of_members(size)
{
// ...
}
Если уничтожается объект класса, который сам содержит объекты класса (например, 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()Такие отдельно создаваемые объекты могут оказаться полезными, но учтите, что members и friends указывают на независимые от них объекты, каждый из которых надо явно размещать и удалять. Кроме того, указатель и объект в свободной памяти суммарно занимают больше места, чем объект-член.
{
// ...
delete members;
delete friends;
}
