Программирование >>  Инициализация объектов класса, структура 

1 ... 246 247 248 [ 249 ] 250 251 252 ... 395


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, но ни в коем случае не для выполнения неявных преобразований. Чтобы избежать такого



1 ... 246 247 248 [ 249 ] 250 251 252 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика