|
Программирование >> Инициализация объектов класса, структура
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) Когда мы пишем:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |