Читать «Справочное руководство по C++» онлайн - страница 67

Бьярн Страустрап

class X {

 //…

public:

 //…

 X(int);

 X(X&);

 ~X();

};

X f(X);

void g()

{

 X a(1);

 X b = f(X(2));

 a = f(b);

}

Здесь нужен временный объект для построения X(2), прежде чем передать его функции f() с помощью X(X&). Альтернативное решение, - построить объект X(2) в памяти, используемой для хранения параметра при первом вызове f(). Помимо этого, временный объект может понадобиться для хранения результата f(X(2)) прежде, чем копировать его в объект b с помощью X(X&), и здесь возможно альтернативное решение: хранить результат f(X(2)) в памяти для объекта b. С другой стороны, существует много функций f(), для которых выполнение выражения a=f(a) требует временного объекта или для параметра a, или для результата f(a), чтобы избежать нежелательного использования памяти, которой приписывается имя a.

Транслятор обязан гарантировать уничтожение временных объектов. Точный момент уничтожения определяется реализацией. С временными объектами можно производить только две операции: выбрать значение объекта (неявно копируя его) для использования в другом выражении, или взять ссылку на него. Если значение временного объекта получено, он считается ненужным и может уничтожаться немедленно. Если на него получена ссылка, то уничтожать его нельзя, пока существует ссылка. Уничтожение должно произойти до выхода из области определенности, в которой был создан временный объект.

Другой вид временных объектов обсуждается в §R.8.4.3.

R.12.3 Преобразования

Преобразования объектов класса можно задать с помощью конструкторов или функций преобразования.

Такие преобразования, обычно называемые пользовательскими, используются неявно в совокупности со стандартными преобразованиями (§R.4). Например, функцию с формальным параметром типа X можно вызывать не только с параметром типа X, но и параметром типа T, если существует преобразование типа T в X. Пользовательские преобразования применяются в тех же ситуациях, что и стандартные: преобразование инициализаторов (§R.8.4), параметров функции (§R.5.2.2), возвращаемых функцией значений (§R.6.6.3, §R.8.2.5), выражений фактических параметров (§R.5), выражений, управляющих циклом и выбором операторов (§R.6.4, §R.6.5) и явные операции преобразования типа (§R.5.2.3, §R.5.4).

Пользовательские преобразования применяются только в случае их однозначности (§R.10.1.1, §R.12.3.2). Преобразования проходят проверку на соответствие правилам доступа (§R.11). Как всегда проверка доступа осуществляется после разрешения неоднозначности (§R.10.4).

Применение преобразований при вызове функции рассматривается на примерах, приведенных ниже, а также обсуждается в §R.13.2.

R.12.3.1 Преобразование с помощью конструктора

Конструктор, имеющий единственный параметр, задает преобразование типа своего фактического параметра в тип его класса, например:

class X {

 //…

public:

 X(int);