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

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

 X(const char*, int = 0);

};

void f(X arg) {

 X a = 1; // a = X(1);

 X b = "Jessie"; // b = X("Jessie",0)

 a = 2; // a = X(2)

 f(3); // f(X(3))

}

Если в классе X нет конструктора, который допускает заданный тип, не делается попытки найти какой-либо конструктор другого класса или функцию преобразования для приведения заданного значения в значение типа,допустимого для конструктора класса X, например:

class X { /*… */ X(int); };

class Y { /*… */ Y(X); };

Y a = 1; // недопустимо: преобразование Y(X(1))

  // не применяется

R.12.3.2 Функции преобразования

Функция-член класса X, имя которой имеет вид,

имя-функции-преобразования:

 operator имя-типа-преобразования

имя-типа-преобразования:

 список-спецификаций-типа opt операция-ptr opt

задает преобразование из типа X в тип, определяемый конструкцией имя-типа-преобразования. Такие функции-члены называются функциями преобразования. В конструкции список-спецификаций-типа нельзя описывать классы, перечисления и имена-typedef, а также нельзя задавать типы формальных параметров и тип возвращаемого значения.

Приведем пример:

class X {

 //…

public:

 operator int();

};

void f(X a)

{

 int i = int(a);

 i = (int)a;

 i = a;

}

Здесь во всех трех операторах присваиваемое значение будет преобразовываться с помощью функции X::operator int(). Пользовательские преобразования не ограничиваются только использованием в присваивании и инициализации, например:

void g(X a, X b)

{

 int i = (a) ? 1+a : 0;

 int j = (a&&b) ? a+b : i;

 if (a) {//…

 }

}

Операции преобразования наследуются. Функции преобразования могут быть виртуальными.

К данному значению неявно применяется не более одного пользовательского преобразования (с помощью конструктора или функции преобразования), например:

class X {

 //…

public:

 operator int();

};

class Y {

 //…

public:

 operator X();

};

Y a;

int b = a; // недопустимо: преобразование

  // a.operator X().operator int() не применяется

int c = X(a); // нормально: a.operator X().operator int()

Пользовательские преобразования осуществляются неявно только при условии их однозначности. Функция преобразования производного класса не закрывает функцию преобразования базового класса, если только они не преобразуют к одному и тому же типу, например:

class X {

public:

 //…

 operator int();

};

class Y: public X {

public:

 //…

 operator void*();

};

void f(Y& a)

{

 if (a) {// ошибка: неоднозначность

 }

}

R.12.4 Деструкторы

Деструктором называется функция-член класса cl с именем ~cl, она используется для уничтожения значений типа cl непосредственно перед уничтожением объекта, содержащего их. Деструктор не имеет формальных параметров и для него нельзя задать тип возвращаемого значения (даже void). Нельзя применять операцию взятия адреса для деструктора. Можно вызывать деструктор для объектов со спецификацией const или volatile, но сам деструктор нельзя описывать с этими спецификациями (§R.9.3.1). Деструктор не может быть и статическим.