|
Программирование >> Инициализация объектов класса, структура
class Account { public: конструктор по умолчанию Account(); имена параметров в объявлении указать необязательно Account( const char*, double=0.0 ); const char* name() { return name; } ... private: ... Account, которые могут быть инициализированы пользователем: }; Ниже приведены два примера правильного определения объекта класса Account, где конструктору передается один или два аргумента: Количество конструкторов у одного класса может быть любым, лишь бы все они имели разные списки формальных параметров. Откуда мы знаем, сколько и каких конструкторов определить? Как минимум, необходимо присвоить начальное значение каждому члену, который в этом нуждается. Например, номер счета либо задается явно, либо генерируется автоматически таким образом, чтобы гарантировать его уникальность. Предположим, что он будет создаваться автоматически. Тогда м1 должны разрешить инициализировать оставшиеся два члена name и balance: Account( const char *name, double open balance ); Объект класса Account, инициализируемый конструктором, можно объявить следующим образом: Account newAcct( Mikey Matz , 0 ); Если же есть много счетов, для которых начальный баланс равен 0, то полезно иметь конструктор, задающий только имя владельца и автоматически инициализирующий balance нулем. Один из способов сделать это - предоставить конструктор вида: Account( const char *name ); Другой способ - включить в конструктор с двумя параметрами значение по умолчанию, равное нулю: Account( const char *name, double open balance = 0.0 ); Оба конструктора обладают необходимой пользователю функциональностью, поэтому оба решения приемлемы. Мы предпочитаем использовать аргумент по умолчанию, поскольку в такой ситуации общее число конструкторов класса сокращается. Нужно ли поддерживать также задание одного лишь начального баланса без указания имени клиента? В данном случае спецификация класса явно запрещает это. Наш конструктор с двумя параметрами, из которых второй имеет значение по умолчанию, предоставляет полный интерфейс для указания начальных значений тех членов класса int main() правильно: в обоих случаях вызается конструктор с двумя параметрами Account acct( Ethan Stern ); Account *pact = new Account( chael Lieberman , 5000 ); if ( strcmp( acct.name(), pact->name() )) ... C++ требует, чтобы конструктор применялся к определенному объекту до его первого использования. Это означает, что как для acct, так и для объекта, на который указывает pact, конструктор будет вызван перед проверкой в инструкции if. Компилятор перестраивает нашу программу, вставляя вызовы конструкторов. Вот как, по псевдокод на C++, иллюстрирующий внутреннюю вставку конструктора int main() { Account acct; acct.Account::Account( Ethan Stern , 0.0); ... всей вероятности, будет модифицировано определение acct внутри main() : Конечно, если конструктор определен как встроенный, то он подставляется в точке вызова. Обработка оператора new несколько сложнее. Конструктор вызывается только тогда, когда он успешно выделил память. Модификация определения pact в несколько псевдокод на C++, иллюстрирующий внутреннюю вставку конструктора при обработке new int main() { ... Account *pact; try { pact = new( sizeof ( Account )); pact->Acct.Account::Account( Michael Liebarman , 5000.0); catch( std::bad alloc ) { оператор new закончился неудачей: конструктор не вызывается ... упрощенном виде выглядит так: в общем случае эти формах эквивалентны Account acct1( Anna Press ); Account acct2 = Account( Anna Press ); Существует три в общем случае эквивалентных формы задания аргументов конструктора: Account acct3 = AAnna Press ; Форма acct3 может использоваться только при задании единственного аргумента. Если аргументов два или более, мы рекомендуем пользоваться формой acct1, хотя допустима рекомендуемая форма вызова конструктора и acct2. Account acct1( Anna Press ); Новички часто допускают ошибку при объявлении объекта, инициализированного увы! работает не так, как ожидалось конструктором по умолчанию: Account newAccount(); Эта инструкция компилируется без ошибок. Однако при попытке использовать объект в ошибка компиляции ... таком контексте: if ( ! newAccount.name() ) ... компилятор не сможет применить к функции нотацию доступа к членам класса. определяет функцию а не объект класса newAccount, объект Определение Account newAccount(); интерпретируется компилятором как определение функции без параметров, которая возвращает объект типа Account. Правильное объявление объекта класса, правильно: определяется объект класса ... инициализируемого конструктором по умолчанию, не содержит пустых скобок: Account newAccount; Определять объект класса, не указывая списка фактических аргументов, можно в том случае, если в нем либо объявлен конструктор по умолчанию, либо вообще нет
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |