C++.Бархатный путь


Конструкторы. Основные свойства - часть 6


void MyProc(); ::::: void MyProc() {/*…*/} ::::: if (MyProc()) {/*…*/} /* Здесь ошибка */ for ( ; MyProc(); ) {/*…*/} /* Здесь ошибка */ if (ComplexType()){/*…*/} /* Это тоже ошибка */

Выражение явного преобразования типа можно расположить справа от символа операции присвоения в операторе присвоения.

ComplexType MyVal = ComplexType (); ComplexType MyVal = ComplexType (25); ComplexType MyVal = (ComplexType) 25;

И опять перед нами так называемый явный вызов конструктора. Но, как сказано в справочном руководстве по C++, "явный вызов конструктора означает не то же самое, что использование того же синтаксиса для обычной функции-члена". Конструктор вызывается не для объекта класса, как другие функции-члены, а для области памяти. Для её преобразования ("превращения") в объект класса.

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

int MyVal = MyProc(); /* Ошибка */ int MyVal = (void)MyProc(); /* Ошибка */

И ещё одно сравнение между конструктором и void-процедурой. Поскольку тип void - это всё же тип, мы можем объявить указатель на void-процедуру.

void MyFunction (void); ::::: void (*MyFunctionPointer) (void);

Указатель на функцию можно настроить на адрес конкретной функции. Для этого существует операция взятия адреса:

MyFunctionPointer = MyFunction; /* Можно так. */ MyFunctionPointer = &MyFunction; /* А можно и так. */

С конструктором всё по-другому. Мы можем определить адрес создаваемого конструктором объекта. Всё то же выражение явного преобразования типа обеспечивает обращение к конструктору, который создаёт в памяти безымянный объект, чей адрес и определяется операцией взятия адреса: if (&ComplexType()) {/*…*/}

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

| |

 




- Начало -  - Назад -  - Вперед -