Не будет виртуальным. Виртуальные деструкторы
Таблица виртуальных функций При динамическом связывании во время выполнения программы вызовов виртуальной функции-элемента перенаправляется функции из соответствующего класса. Для этой цели используется таблица виртуальных функций, называемая vtable, которая реализована в виде массива, содержащего указатели на функции. Каждый класс, содержащий виртуальные функции, имеет таблицу vtable. Для каждой виртуальной функции класса в vtable включается указатель на функцию, используемую для объекта этого класса. Виртуальная функция, используемая в конкретном классе, может быть либо определена в нем, либо унаследована, непосредственно или косвенно, от стоящнго выше в иерархии базого класса. Определенная в базовом классе виртуальная функция-элемент может быть замещена в произвольном классе, но произвольные классы не должны делать это в обязательном порядке. Это значит, что произвольный класс может использовать виртуальную функцию-элемент из базового класса, что будет отражено в vtable. Каждый объект класса с виртуальными функциями содержит указатель на vtable своего класса. Этот указатель для программиста недоступен. Соответствующий указатель на функцию выбирается из vtable и разыменовывается; на этом завершается формирование вызова виртуальной функции во время выполнения программы. На просмотр vtable и разыменовывание указателя требуются незначительные ресурсы системы. Случаи, когда вызов виртуальной функции не будет виртуальным Тип виртуальной функции не может быть переопределен в производных классах. Исключением является случай, когда возвращаемый тип виртуальной функции является указателем или ссылкой на порожденный класс, а виртуальная функция основного класса - указателем или ссылкой на базовый класс. В производных классах функция может иметь список параметров, отличный от параметров виртуальной функции базового класса. В этом случае эта функция будет не виртуальной, а перегруженной. При этом спецификатор virtual игнорируется. Вызов функций должен производиться с учетом списка параметров.
Виртуальные деструкторы При использовании полиморфизма в работе с динамически выделенными объектами иерархии классов могут возникать трудности. Если объекты разрушаются при помощи операции delete с указателем на базовый класс, то вызывается деструктор базового класса. Это происходит независимо от типа объекта, на который ссылается указатель на базовый класс, и от того факта, что деструктор каждого класса имеет другое имя. Имеется простое решение этой проблемы - деструктор базового класса объявляется виртуально. Это приведет к тому, что деструкторы всех производных классов будут виртуальными, даже если их имена отличаются от имени деструктора базового класса. И теперь, если объект в иерархии разрушается при помощи операции delete, а указатель, ссылающийся на объект, является указателем на базовый класс, вызывается деструктор соответствующего производного класса.
Ввод-вывод файлов. Потоки ввода-вывода. Библиотека ввода-вывода (iostream). Группы классов библиотеки ввода вывода Для начала рассмотрим пример: #include <stream.h> main() { cout << "Hello, world\n"; } Строка #include <stream.h> сообщает компилятору, чтобы он включил стандартные возможности потока ввода и вывода, находящиеся в файле stream.h. Без этих описаний выражение cout << "Hello, world\n" не имело бы смысла. Операция << ("поместить в") пишет свой первый аргумент во второй (в данном случае, строку "Hello, world\n" в стандартный поток вывода cout). Программирующим на C << известно как операция сдвига влево для целых. Такое использование << не утеряно, просто в дальнейшем << было определено для случая, когда его левый операнд является потоком вывода.
Ввод производится с помощью операции >> ("извлечь из") над стандартным потоком ввода cin. Описания cin и >>, конечно же, находятся в <stream.h>. Операцию вывода << можно применять к ее собственному результату, так что несколько команд вывода можно записать одним оператором. Потоки Механизм для ввода-вывода в Си++ называется потоком. Название произошло от того,что информация вводится и выводится в виде потока байтов – символ за символом. Класс istream реализует поток ввода, класс ostream – поток вывода. Эти классы определены в файле заголовков iostream.h. Библиотека потоков ввода-вывода определяет три глобальных объекта: cout,cin и cerr. cout называется стандартным выводом, cin – стандартным вводом, cerr – стандартным потоком сообщений об ошибках. cout и cerr выводят на терминал и принадлежат к классу ostream, cin имеет тип istream и вводит с терминала. Разница между cout и cerr существенна в Unix – они используют разные дескрипторы для вывода. В других системах они существуют больше для совместимости. Вывод осуществляется с помощью операции <<, ввод с помощью операции >>. Выражение cout << "Пример вывода: " << 34;напечатает на терминале строку "Пример вывода", за которым будет выведено число 34. Выражение int x;cin >> x;введет целое число с терминала в переменную x. (Разумеется, для того, чтобы ввод произошел, на терминале нужно напечатать какое-либо число и нажать клавишу возврат каретки.) Операции << и >> для потоков В классах iostream операции >> и << определены для всех встроенных типов языка Си++ и для строк (тип char*). Если мы хотим использовать такую же запись для ввода и вывода других классов, определенных в программе, для них нужно определить эти операции. Как показано в примере класса String, операция <<, во-первых, является не методом класса String, а отдельной функцией. Она и не может быть методом класса String, поскольку ее правый операнд – объект класса ostream. С точки зрения записи, она могла бы быть методом класса ostream, но тогда с добавлением нового класса приходилось бы модифицировать класс ostream, что невозможно – каждый бы модифицировал стандартные классы, поставляемые вместе с компилятором. Когда же операция << реализована как отдельная функция, достаточно в каждом новом классе определить ее, и можно использовать запись:
Во-вторых, операция << возвращает в качестве результата ссылку на поток вывода. Это позволяет использовать ее в выражениях типа приведенного выше, соединяющих несколько операций вывода в одно выражение. Аналогично реализована операция ввода. Для класса istream она определена для всех встроенных типов языка Си++ и указателей на строку символов. Если необходимо, чтобы класс, определенный в программе, позволял ввод из потока, для него нужно определить операцию >> в качестве функции friend. токовые классы представляют объектно-ориентированный вариант функций ANSI-C. Поток данных между источником и приемником при этом обладает следующими свойствами.
Пример шаблона потокового класса. template<class charT, class traits = ios_traits<charT> >class basic_istream: virtual public basic_ios<charT, traits>;Потоковые классы в С++.
Библиотека потоковых классов С++ построена на основе двух базовых классов: ios и streambuf. Класс streambuf обеспечивает организацию и взаимосвязь буферов ввода-вывода, размещаемых в памяти, с физическими устройствами ввода-вывода. Методы и данные класса streambuf программист явно обычно не использует. Этот класс нужен другим классам библиотеки ввода-вывода. Он доступен и программисту для создания новых классов на основе уже существующих. Класс ios содержит средства для форматированного ввода-вывода и проверки ошибок. Стандартные потоки (istream, ostream, iostream) служат для работы с терминалом. Строковые потоки (istrstream, ostrstream, strstream) служат для ввода-вывода из строковых буферов, размещенных в памяти. Файловые потоки (ifstream, ofstream, fstream) служат для работы с файлами. ios базовый потоковый класс streambuf буферизация потоков istream потоки ввода ostream потоки вывода iostream двунаправленные потоки iostream_withassign поток с переопределенной операцией присваивания istrstream строковые потоки ввода ostrstream строковые потоки вывода strstream двунаправленные строковые потоки ifstream файловые потоки ввода ofstream файловые потоки вывода fstream двунаправленные файловые потоки Потоковые классы, их методы и данные становятся доступными в программе, если в неё включен нужный заголовочный файл. iostream.h - для ios, ostream, istream. strstream.h - для strstream, istrstream, ostrstream. fstream.h - для fstream, ifstream, ofstream.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|