Программирование >>  Инициализация объектов класса, структура 

1 ... 218 219 220 [ 221 ] 222 223 224 ... 395


class Account {

public:

имена параметров в объявлении указывать необязательно Account( const char*, double=0.0 );

const char* name() { return name; }

...

private:

...

исключен:

Теперь при объявлении каждого объекта Account в конструкторе обязательно надо указать как минимум аргумент типа С-строки, но это скорее всего бессм1сленно. Почему? Контейнерные классы (например, vector) требуют, чтобы для класса помещаемых в них элементов был либо задан конструктор по умолчанию, либо вообще никаких конструкторов. Аналогичная ситуация имеет место при выделении динамического массива объектов класса. Так, следующая инструкция вызвала бы ошибку

ошибка: требуется конструктор по умолчанию для класса Account

компиляции для новой версии Account:

Account *pact = new Account[ new client cnt ];

На практике часто требуется задавать конструктор по умолчанию, если имеются какие-либо другие конструкторы.

А если для класса нет разумных значений по умолчанию? Например, класс Account требует задавать для любого объекта фамилию владельца счета. В таком случае лучше всего установить состояние объекта так, чтобы было видно, что он еще не

конструктор по умолчанию для класса Account inline Account:: Account() { name = 0; balance = 0.0; acct nmbr = 0;

инициализирован корректными значениями:

Однако в функции-члены класса Account придется включить проверку целостности объекта перед его использованием.

объявлений конструкторов. Если в классе объявлен хотя бы один конструктор, то не разрешается определять объект класса, не вызывая ни одного из них. В частности, если в классе определен конструктор, принимающий один или более параметров, но не определен конструктор по умолчанию, то в каждом определении объекта такого класса должны присутствовать необходимые аргументы. Можно возразить, что не имеет смысла определять конструктор по умолчанию для класса Account, поскольку не бывает счетов без имени владельца. В пересмотренной версии класса Account такой конструктор



конструктор по умолчанию класса Account с использованием списка инициализации членов inline Account:: Account()

: name(0), balance( 0.0 ), acct nmbr( 0 )

умолчанию можно переписать следующим образом:

Такой список допустим только в определении, но не в объявлении конструктора. Он помещается между списком параметров и телом конструктора и отделяется двоеточием. Вот как выглядит наш конструктор с двумя параметрами при частичном использовании

inline Account::

Account( const ch

: balance( opening bal

Account ( const char* name, double opening bal )

Via 1 ЭП fo ( -i nrr Via 1

name = new char[ strlen(name)+1 ]; strcpy( name, name );

acct nmbr = get unique acct nmbr();

списка инициализации членов:

get unique acct nmibr() - это не являющаяся открытой функция-член, которая возвращает гарантированно не использованный ранее номер счета.

Конструктор нельзя объявлять с ключевыми словами const или volatile (см. раздел

class Account {

public:

Account() const; ошибка

Account() volatile; ошибка

...

13.3.5), поэтому приведенные записи неверны:

Это не означает, что объекты класса с такими спецификаторами запрещено инициализировать конструктором. Просто к объекту применяется подходящий конструктор, причем без учета спецификаторов в объявлении объекта. Константность объекта класса устанавливается после того, как работа по его инициализации завершена, и пропадает в момент вызова деструктора. Таким образом, объект класса со спецификатором const считается константным с момента завершения работы конструктора до момента запуска деструктора. То же самое относится и к спецификатору volatile.

Рассмотрим следующий фрагмент программ::

Существует и альтернативн1й синтаксис: список инициализации членов, в котором через занятую указываются имена и начальные значения. Например, конструктор но



в каком-то заголовочном файле

extern void print( const Account &acct );

...

int main()

преобразует строку oops в объект класса с помощью конструктора Account::Account(

Account oops , 0.0 )

print( oops );

...

По умолчанию конструктор с одним параметром (или с несколькими - при условии, что все параметры, кроме первого, имеют значения по умолчанию) играет роль оператора преобразования. В этом фрагменте программы конструктор Account неявно применяется компилятором для трансформации литеральной строки в объект класса Account при вызове print() , хотя в данной ситуации такое преобразование не нужно.

Непреднамеренные неявные преобразования классов, например трансформация oops в объект класса Account, оказались источником трудно обнаруживаемых ошибок. Поэтому в стандарт C++ было добавлено ключевое слово explicit, говорящее

class Account {

public:

explicit Account( const char*, double=0.0 );

компилятору, что такие преобразования не нужны: };

Данный модификатор применим только к конструктору. (Операторы преобразования и слово explicit обсуждаются в разделе 15.9.2.)

14.2.1. Конструктор по умолчанию

Конструктором по умолчанию называется конструктор, который можно вызывать, не задавая аргументов. Это не значит, что такой конструктор не может принимать аргументов; просто с каждым его формальным параметром ассоциировано значение по

все это конструкторы по умолчанию

Account::Account() { ... }

iStack::iStack( int size = 0 ) { ... }

умолчанию:

Complex::Complex(double re=0.0, double im=0.0) Когда мы пишем:



1 ... 218 219 220 [ 221 ] 222 223 224 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика