|
Программирование >> Инициализация объектов класса, структура
Accounts Account:: operator=( const Account srhs ) { не надо присваивать самому себе if ( this != srhs ) { вызается string::operator=( const strings ) name = rhs. name; balance = rhs. balance; return *this; присваивания с учетом того, что name - это объект класса string: Чтобы запретить почленное копирование, мы поступаем так же, как и в случае почленной инициализации: объявляем оператор закрытым и не предоставляем его определения. Копирующий конструктор и копирующий оператор присваивания обычно рассматривают вместе. Если необходим один, то, как правило, необходим и другой. Если запрещается один, то, вероятно, следует запретить и другой. Упражнение 14.17 Реализуйте копирующий оператор присваивания для каждого из классов, определенных в упражнении 14.14 из раздела 14.6. Упражнение 14.18 Нужен ли копирующий оператор присваивания для того класса, который вы выбрали в упражнении 14.3 из раздела 14.2? Если да, реализуйте его. В противном случае объясните, почему он не нужен. 14.8. Соображения эффективности A В общем случае объект класса эффективнее передавать функции по указателю или по ссылке, нежели по значению. Например, если дана функция с сигнатурой: bool sufficient funds( Account acct, double ); то при каждом ее вызове требуется выполнить почленную инициализацию формального параметра acct значением фактического аргумента-объекта класса Account. Если же bool sufficient funds( Account *pacct, double ); функция имеет любую из таких сигнатур: bool sufficient funds( Account sacct, double ); Однако почленное присваивание по умолчанию для объектов класса Account не подходит из-за acct nmbr. Нужно реализовать явный копирующий оператор задача решается, но для больших матриц эффективность может оказаться неприемлемо низкой Matrix operator+( const Matrixs m1, const Matrixs m2 ) Matrix result; выполнить арифметические операции return result; оператор сложения: Matrix a, b; ... в обоих случаях вызывается operator+() Matrix c = a + b; Этот перегруженный оператор позволяет пользователю писать a = b + c; Однако возврат результата по значению может потребовать слишком больших затрат времени и памяти, если Matrix представляет собой большой и сложный класс. Если эта операция выполняется часто, то она, вероятно, резко снизит производительность. более эффективно, но после возврата адрес оказывается недействительным это может привести к краху программы Matrixs operator+( const Matrixs m1, const Matrixs m2 ) trix result; выполнить сложение Matrix return result; Следующая пересмотренная реализация намного увеличивает скорость: но при этом происходят частые сбои программы. Дело в том, что значение переменной result не определено после выхода из функции, в которой она объявлена. (Мы возвращаем ссылку на локальный объект, который после возврата не существует.) Значение возвращаемого адреса должно оставаться действительным после выхода из функции. В приведенной реализации возвращаемый адрес не затирается: то достаточно скопировать адрес объекта Account. В этом случае никакой инициализации класса не происходит (см. обсуждение взаимосвязи между ссылочными и указательными параметрами в разделе 7.3). Хотя возвращать указатель или ссылку на объект класса также более эффективно, чем сам объект, но корректно запрограммировать это достаточно сложно. Рассмотрим такой нет возможности гарантировать отсутствие утечки памяти поскольку матрица может быть большой, утечки будут весьма заметни Matrixs operator+( const Matrixs m1, const Matrixs m2 ) { Matrix *result = new Matrix; выполнить сложение ... return *result; Однако это неприемлемо: происходит большая утечка памяти, так как ни одна из частей программы не отвечает за применение оператора delete к объекту по окончании его использования. Вместо оператора сложения лучше применять именованную функцию, которой в качестве это обеспечивает нужн эффективность, но не является интуитивно понятным для пользователя void mat add( Matrix sresult, const Matrixs m1, const Matrixs m3 ) вычислить результат третьего параметра передается ссылка, где следует сохранить результат: Таким образом, проблема производительности решается, но для класса уже нельзя использовать операторный синтаксис, так что теряется возможность инициализировать более не поддерживается объекты Matrix c = a + b; тоже не поддерживается и использовать их в выражениях: if ( a + b > c ) ... Неэффективный возврат объекта класса - слабое место С++. В качестве одного из решений предлагалось расширить язык, введя имя возвращаемого функцией объекта:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |