Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 60
Текст из файла (страница 60)
g e t a O « endl;cout « "ob2: " « ob2.geta() « endl;return 0;'праЖненияения]1. В примере 3 f если спецификатор explicit указать только для конструктораmyclass(int), можно ли будет выполнить неявное преобразование также и дляконструктора myclass(char *)? (Подсказка: попробуйте и посмотрите, что получится.)2. Работоспособен ли следующий фрагмент программы?class Demo {double x;public:Demo{double i) ( x = i; }Demo counter = 10;3. Попытайтесь оправдать введение ключевого слова explicit. (Другими словами,объясните, почему неявное преобразование конструкторов в некоторых случаях может оказаться нежелательным.)13.6.
Спецификаторы сборкии ключевое слово asmВ C++ поддерживаются два важных механизма для облегчения связи C++ сдругими языками программирования. Первым является спецификатор сборки(linkage specifier), который сообщает компилятору, что одна или более функций вашей программы на C++ будет компоноваться с другим языком программирования, который может иметь другие соглашения о передаче параметров процедуре заполнения стека и т.
д. Вторым является ключевое словоasm, которое позволяет вставлять в исходную профамму команды ассемблера. Оба этих механизма рассматриваются в этом разделе.По умолчанию все функции программы на C++ компилируются и компонуются как функции C++. Однако компилятору C++ можно сообщить, чтофункция будет компоноваться как функция, написанная на другом языкеg.Пространстваименидругиетемы_409программирования. Все компиляторы C++ допускают компоновку функцийлибо как функций С, либо как функций C++.
Некоторые также допускаюткомпоновку функций для таких языков, как Pascal, Ada или FORTRAN.Чтобы компоновать функции для других языков программирования, используется следующая основная форма спецификатора сборки:extern "язак" прототип функции;Здесь язык — это название языка программирования, как функцию котороговы хотите компоновать вашу функцию.
Если необходимо использовать спецификатор сборки более чем для одной функции, используется такая егоосновная форма:ex-tern "язык" {прототипа функций;Все спецификаторы сборки должны быть глобальными; их нельзя задаватьвнутри функций.Чаще всего в программы на C++ приходится вставлять фрагменты программна С. Путем задания сборки с "С" вы предотвращаете искажения (mangling)имен функций информацией о типе. Поскольку в C++ имеется возможность перегружать функции и создавать функции-члены, то каждому именифункции обычно сопутствует некоторая информация о ее типе. С другойстороны, так как язык С не поддерживает ни перегрузки функций, нифункций-членов, он не может распознавать имена функций, искаженныеинформацией об их типе.
Указание компилятору необходимости сборки с"С" позволяет решить проблему.Хотя вполне возможно совместно компоновать ассемблерные подпрофаммыс программами на C++, часто легче использовать язык ассемблера в процессе написания программ на C++. В C++ поддерживается специальное ключевое слово asm, позволяющее вставлять ассемблерные инструкции в функции C++. Преимущество встроенного ассемблера в том, что ваша программаполностью компилируется как программа на C++, и нет необходимостираздельно с ней компилировать, а затем совместно компоновать ассемблерные файлы. Здесь показана основная форма ключевого слова asm:asm <"ас_псядац»");где ас_инструкция — это ассемблерная инструкция, которая будет встроенав вашу программу.Важно отметить, что в некоторых компиляторах поддерживаются следующиетри, несколько иные формы инструкции asm:asm ас_инструкцкя;asm ас инструкция физический конец строки410_СамоучительC++asm {последовательность ассемблерных инструкцийЗдесь ассемблерные инструкции не выделяются кавычками.
Для правильного встраивания ассемблерных инструкций вам понадобится изучить техническую документацию на ваш компилятор.S среде программирования Microsoft Visual C++ для встраивания ассемблерного кода используется инструкцияasm. So всем остальном эта инструкция аналогична только что описанной инструкции asm.Примеры1. В этой программе функция func() компонуется не как функция C++, а какфункция С:// Демонстрация спецификатора сборкиttinclude <iostream>using namespace std;extern "C" int func(int x ) ; // компонуется как функция С// Теперь функция компонуется как функция С.int func(int x)(return x/3;Теперь эта функция может компоноваться с программой, которая компилировалась компилятором С.2.
В представленной ниже программе компилятору сообщается, что функцииП(), й() и f3() должны компоноваться как функции С:extern "С" {void f 1 ( ) ;int f 2 ( i n t x ) ;double f3 {double x, int *p) ;3. В этом фрагменте в функцию func() вставляется несколько ассемблерныхинструкций:Глава 13. Пространства имен и другие темы411/ / Н е пытайтесь выполнить эту функцию!void funcO{asm ("mov bp, sp"};asm {"push ax");asm ("mov cl, 4 " ) ;Для успешного использования встроенного ассемблера вы должны бытьопытным программистом на языке ассемблера. Кроме этого, нужно тщательно изучить техническую документацию на ваш компилятор.{УпражненияИзучите те разделы технической документации на ваш компилятор, которыеотносятся к спецификаторам сборки и интерфейсу с ассемблером.13.7.
Массивыв качестве объектов ввода/выводаПомимо ввода/вывода на экран и в файл, в C++ поддерживается целый рядфункций, в которых в качестве устройств для ввода и вывода используютсямассивы. Хотя ввод/вывод с использованием массивов (array-based I/O) вC++ концептуально перекликается с аналогичным вводом/выводом в С (вособенности это касается функций sscanfQ и sprintf() языка С), ввод/выводс использованием массивов в C++ более гибкий и полезный, поскольку онпозволяет интегрировать в него определенные пользователем типы данных.Хотя охватить все аспекты массивов в качестве объектов ввода/вывода невозможно, здесь рассматриваются их наиболее важные и часто используемые свойства.Важно понимать, что для реализации ввода/вывода с использованием массивов тоже нужны потоки.
Все, что вы узнали о вводе/выводе C++ из глав 8и 9 применимо и к вводу/выводу с использованием массивов. При этом,чтобы узнать о всех достоинствах массивов в качестве объектов ввода/вывода, вам следует познакомиться с несколькими новыми функциями.Эти функции предназначены для связывания нужного потока с некоторой412Самоучитель C++областью памяти. После того как эта операция выполнена, весь ввод/выводпроизводится посредством тех самых функций для ввода и вывода, о которых вы уже знаете.Перед тем как начать пользоваться массивами в качестве объектов ввода/вывода, необходимо удостовериться в том, что в вашу программу включен заголовок <strstream>. В этом заголовке определяются классы istrstream,ostrstream и strstream.
Эти классы образуют, соответственно, основанные наиспользовании массивов потоки для ввода, вывода и ввода/вывода. Базовымдля этих классов является класс ios, поэтому все функции и манипуляторыклассов istream, ostream и iostream имеются также и в классах istrstream,ostrstream и strstream.Для вывода в символьный массив используйте следующую основную формуконструктора класса ostrstream:ostrstream лотох_вывода (char *буфер, streamsize размер,opemnode режим = ios: :out) ;Здесь поток_вывода — это поток, который связывается с массивом, заданным через указатель буфер.
Параметр размер определяет размер массива.Параметр режим по умолчанию обычно настроен на обычный режим вывода, но вы можете задать любой, определенный в классе ios, флаг режимавывода. (За подробностями обращайтесь к главе 9.)После того как массив открыт для вывода, символы будут выводиться в массив вплоть до его заполнения. Переполнения массива произойти не может.Любая попытка переполнения массива приведет к ошибке ввода/вывода.Для определения количества записанных в массив символов используйтеприведенную ниже функцию-член pcount():int pcountO ;Функция должна вызываться только в связи с потоком и возвращает оначисло символов, записанных в массив, включая нулевой символ завершения.Чтобы открыть массив для ввода из него, используйте следующую формуконструктора класса istrstream:istrstream аоток_ввода(const char*буфер);Здесь буфер — это указатель на массив, из которого будут вводиться символы.Поток ввода обозначен через поток_ввода.
При считывании входной информации из массива, функция eof() возвращает истину при достижении концамассива.Чтобы открыть массив для ввода/вывода, используйте следующую формуконструктора класса strstream:strstream поток_ввод_в*тод (char *буфер, streamsize размер,openmode режим = ios : : in | ios: : out) ;Глава 13. Пространства имен и другие темы413Здесь поток__ввод_вывод — это поток ввода/вывода, для которого в качествеобъекта ввода/вывода через указатель буфер задан массив длиной в размерсимволов.Важно помнить, что все описанные ранее функции ввода/вывода работают ис массивами, включая функции ввода/вывода двоичных файлов и функциипроизвольного доступа..Применение потоковых классов для символьных массивов резко осуждаетсястандартом Standard C++.