Язык программирования C++. Вводный курс



Соображения эффективности A


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

bool sufficient_funds( Account acct, double );

то при каждом ее вызове требуется выполнить почленную инициализацию формального параметра acct

значением фактического аргумента-объекта класса Account. Если же функция имеет любую из таких сигнатур:

bool sufficient_funds( Account *pacct, double );

bool sufficient_funds( Account &acct, double );

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

Хотя возвращать указатель или ссылку на объект класса также более эффективно, чем сам объект, но корректно запрограммировать это достаточно сложно. Рассмотрим такой оператор сложения:

// задача решается, но для больших матриц эффективность может

// оказаться неприемлемо низкой

Matrix

operator+( const Matrix& m1, const Matrix& m2 )

{

   Matrix result;

   // выполнить арифметические операции ...

   return result;

}

Этот перегруженный оператор позволяет пользователю писать

Matrix a, b;

// ...

// в обоих случаях вызывается operator+()

Matrix c = a + b;

a = b + c;

Однако возврат результата по значению может потребовать слишком больших затрат времени и памяти, если Matrix

представляет собой большой и сложный класс. Если эта операция выполняется часто, то она, вероятно, резко снизит производительность.

Следующая пересмотренная реализация намного увеличивает скорость:

// более эффективно, но после возврата адрес оказывается недействительным

// это может привести к краху программы

Matrix&

operator+( const Matrix& m1, const Matrix& m2 )

{

   Matrix result;

   // выполнить сложение ...

   return result;

}

но при этом происходят частые сбои программы. Дело в том, что значение переменной result не определено после выхода из функции, в которой она объявлена. (Мы возвращаем ссылку на локальный объект, который после возврата не существует.)




Содержание  Назад  Вперед