Читаем C++ полностью

Действие ввода cin»»x выше возвращает istream amp;. Это знчение неявно преобразуется к значению, которое указывает сотояние cin, а уже это значение может проверяться оператором while (см. #8.4.2). Однако определять преобразование из оного типа в другой так, что при этом теряется информация, обычно не стоит.

<p>6.3.3 Неоднозначности</p>

Присваивание объекту (или инициализация объекта) класса X является допустимым, если или присваиваемое значение является X, или существует единственное преобразование присваивемого значения в тип X. В некоторых случаях значение нужного типа может быть построено с помощью нескольких применений конструкторов или операций преобразования. Это должно делаться явно; допустим только один уровень неявных преобразований, определенных пользователем. Иногда значение нужного типа может быть посроено более чем одним способом. Такие случаи являются недпустимыми. Например:

class x (* /* ... */ x(int); x(char*); *); class y (* /* ... */ y(int); *); class z (* /* ... */ z(x); *);

overload f; x f(x); y f(y);

z g(z);

f(1); // недопустимо: неоднозначность f(x(1)) или f(y(1)) f(x(1)); f(y(1)); g(«asdf»); // недопустимо: g(z(x(«asdf»))) не пробуется g(z(«asdf»));

Определяемые пользователем преобразования рассматриваюся только в том случае, если без них вызов разрешить нельзя. Например:

class x (* /* ... */ x(int); *) overload h(double), h(x); h(1);

Вызов мог бы быть проинтерпретирован или как h(double(1)), или как h(x(1)), и был бы недопустим по правилу единственности. Но первая интерпретация использует только стандартное преобразование и она будет выбрана по правилам, приведенным в #4.6.7.

Правила преобразования не являются ни самыми простыми для реализации и документации, ни наиболее общими из тех, кторые можно было бы разработать. Возьмем требование единтвенности преобразования. Более общий подход разрешил бы копилятору применять любое преобразование, которое он сможет найти; таким образом, не нужно было бы рассматривать все воможные преобразования перед тем, как объявить выражение дпустимым. К сожалению, это означало бы, что смысл программы зависит от того, какое преобразование было найдено. В резултате смысл программы неким образом зависел бы от порядка опсания преобразований. Поскольку они часто находятся в разных исходных файлах (написанных разными людьми), смысл программы будет зависеть от порядка компоновки этих частей вместе. Есть другой вариант – запретить все неявные преобразования. Нет ничего проще, но такое правило приведет либо к неэлегантным пользовательским интерфейсам, либо к бурному росту перегрженных функций, как это было в предыдущем разделе с complex.

Самый общий подход учитывал бы всю имеющуюся информацию о типах и рассматривал бы все возможные преобразования. Напрмер, если использовать предыдущее описание, то можно было бы обработать aa=f(1), так как тип aa определяет единственность толкования. Если aa является x, то единственное, дающее в рзультате x, который требуется присваиванием, – это f(x(1)), а если aa – это y, то вместоэтого будет использоваться f(y(1)). Самый общий подход справился бы и с g(«asdf»), поскольку единственной интерпретацией этого может быть g(z(x(«asdf»))). Сложность этого подхода в том, что он требует расширенного нализа всего выражения для того, чтобы определить интерпретцию каждой операции и вызова функции. Это приведет к замедлнию компиляции, а также к вызывающим удивление интерпретацим и сообщениям об ошибках, если компилятор рассмотрит преоразования, определенные в библиотеках и т.п. При таком подхде компилятор будет принимать во внимание больше, чем, как можно ожидать, знает пишущий программу программист!

<p>6.4 Константы</p>

Константы классового типа определить невозможно в том смысле, в каком 1.2 и 12e являются константами типа double. Вместо них, однако, часто можно использовать константы осноных типов, если их реализация обеспечивается с помощью фунций членов. Общий аппарат для этого дают конструкторы, полчающие один параметр. Когда конструкторы просты и подставляются inline, имеет смысл рассмотреть в качестве константы вызов конструктора. Если, например, в «comlpex.h» есть описание класса comlpex, то выражение zz1*3+zz2*comlpex(1,2) даст два вызова функций, а не пять. К двум вызовам функций приведут две операции *, а операция + и конструктор, к которому обращаются для создания comlpex(3) и comlpex(1,2), будут расширены inline.

<p>6.5 Большие объекты</p>

При каждом применении для comlpex бинарных операций, описанных выше, в функцию, которая реализует операцию, как параметр передается копия каждого операнда. Расходы на копрование каждого double заметны, но с ними вполне можно примриться. К сожалению, не все классы имеют небольшое и удобное представление. Чтобы избежать ненужного копирования, можно описать функции таким образом, чтобы они получали ссылочные параметры. Например:

class matrix (* double m[4][4]; public: matrix; friend matrix operator+(matrix amp;, matrix amp;); friend matrix operator*(matrix amp;, matrix amp;); *);

Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT
Программист-прагматик. Путь от подмастерья к мастеру
Программист-прагматик. Путь от подмастерья к мастеру

Находясь на переднем крае программирования, книга "Программист-прагматик. Путь от подмастерья к мастеру" абстрагируется от всевозрастающей специализации и технических тонкостей разработки программ на современном уровне, чтобы исследовать суть процесса – требования к работоспособной и поддерживаемой программе, приводящей пользователей в восторг. Книга охватывает различные темы – от личной ответственности и карьерного роста до архитектурных методик, придающих программам гибкость и простоту в адаптации и повторном использовании.Прочитав эту книгу, вы научитесь:Бороться с недостатками программного обеспечения;Избегать ловушек, связанных с дублированием знания;Создавать гибкие, динамичные и адаптируемые программы;Избегать программирования в расчете на совпадение;Защищать вашу программу при помощи контрактов, утверждений и исключений;Собирать реальные требования;Осуществлять безжалостное и эффективное тестирование;Приводить в восторг ваших пользователей;Формировать команды из программистов-прагматиков и с помощью автоматизации делать ваши разработки более точными.

А. Алексашин , Дэвид Томас , Эндрю Хант

Программирование / Книги по IT