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