|
Программирование >> Инициализация объектов класса, структура
class Date { public: попробуйте догадаться, какой именно член возвращается! operator int(); private: int month, day, year; конвертера может оказаться непонятным читателю программы: }; Какое значение должен вернуть конвертер int() класса Date? Сколь бы основательными ни были причины для того или иного решения, читатель останется в недоумении относительно того, как пользоваться объектами класса Date, поскольку между ними и целыми числами нет явного логического соответствия. В таких случаях лучше вообще не определять конвертер. 15.9.2. Конструктор как конвертер Набор конструкторов класса, принимающих единственный параметр, например, SmallInt(int) класса SmallInt, определяет множество неявных преобразований в значения типа SmallInt. Так, конструктор SmallInt(int) преобразует значения типа extern void calc( SmallInt ); int i; необходимо преобразовать i в значение типа SmallInt необходимо преобразовать i в значение типа это достигается применением SmallInt(int) int в значения типа SmallInt. calc( i ); При вызове calc(i) число i преобразуется в значение типа SmallInt с помощью конструктора SmallInt(int) , вызванного компилятором для создания временного объекта нужного типа. Затем копия этого объекта передается в calc(), как если бы вызов функции был записан в форме: Token::operator SmallInt() а затем результат привести к типу int - тоже с помощью пользовательского конвертера Token::operator int() Вызов calc(tok) помечается компилятором как ошибка, так как не существует неявного преобразования из типа Token в тип int. Если логического соответствия между типом конвертера и типом класса нет, назначение Псевдокод на C++ создается временн объект типа SmallInt SmallInt temp = SmallInt( i ); calc( temp ); Фигурные скобки в этом примере обозначают время жизни данного объекта: он уничтожается при выходе из функции. class Number { public: создание значения типа Number из значения типа SmallInt Number( const SmallInt s ); ... Типом параметра конструктора может быть тин некоторого класса: }; В таком случае значение типа SmallInt можно использовать всюду, где допустимо extern void func( Number ); SmallInt si(87) ; int main() { вызывается Number( const SmallInt s ) func( si ); ... значение типа Number: Если конструктор используется для выполнения неявного преобразования, то должен ли тип его параметра точно соответствовать типу подлежащего преобразованию значения? Например, будет ли в следующем коде вызван SmallInt(int) , определенный в классе extern void calc( SmallInt ); double dobj; вызывается ли SmallInt(int)? Да dobj преобразуется приводится от double к int стандартным преобразованием SmiallInt, для приведения dobj к тину SmiallInt? calc( dobj ); Если необходимо, к фактическому аргументу применяется последовательность стандартных преобразований до того, как вызвать конструктор, выполняющий определенное пользователем преобразование. При обращении к функции calc() употребляется стандартное преобразование dobj из типа double в тип int. Затем уже для приведения результата к тину SmallInt вызывается SmallInt(int). class Number { public: public: никогда не использовать для неявных преобразований explicit Numer( const SmallInt & ); ... употребления конструктора, объявим его явн1м (explicit): Компилятор никогда не применяет явные конструкторы для выполнения неявных extern void func( Number ); SmallInt si(87); int main() { ошибка: не существует неявного преобразования из SmallInt в Number func( si ); ... преобразований типов: Однако такой конструктор все же можно использовать для преобразования типов, если SmallInt si(87); int main() { ошибка: не существует неявного преобразования из SmallInt в Number func( si ); func( Number( si ) ); правильно: приведение типа func( static cast< Number >( si ) ); правильно: приведение типа оно запрошено явно в форме оператора приведения типа: 15.10. Выбор преобразования A Определенное пользователем преобразование реализуется в виде конвертера или конструктора. Как уже было сказано, после преобразования, выполненного конвертером, разрешается использовать стандартное преобразование для приведения возвращенного значения к целевому типу. Трансформации, выполненной конструктором, также может предшествовать стандартное преобразование для приведения типа аргумента к типу формального параметра конструктора. Компилятор неявно использует конструктор с единственным параметром для преобразования его типа в тип класса, к которому принадлежит конструктор. Однако иногда удобнее, чтобы конструктор Number(const SmallInt&) можно было вызывать только для инициализации объекта типа Number значением типа SmallInt, но ни в коем случае не для выполнения неявных преобразований. Чтобы избежать такого
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |