
- •Принципы ооп:
- •Ооп, как средство обеспечения требований предъявляемых к современному программному обеспечению
- •Причины использования перегрузки функций
- •Конструкторы и деструкторы производных классов.
- •Полиморфизм и виртуальные функции, раннее и позднее связывание.
- •Форматирование данных, флаги и манипуляторы потоков.
- •Пример форматирования
- •Манипуляторы без параметров:
- •Int I, // параметр обычного типа
Форматирование данных, флаги и манипуляторы потоков.
Непосредственное применение операций вывода << (включение в поток) и ввода >> (извлечение из потока) к стандартным потокам cout, cin, cerr, clog для данных базовых типов приводит к использованию "умалчиваемых" форматов внешнего представления пересылаемых значений.
Форматы могут быть изменены программистом с помощью флагов форматирования. Эти флаги унаследованы всеми потоками библиотеки из базового класса ios. Флаги реализованы в виде отдельных фиксированных битов чисел типа long, поэтому несколько флагов с помощью логических битовых выражений можно объединять, тем самым по-разному комбинируя свойства потока. Некоторые флаги:
left = 0x0002 – вывод значения с левым выравниванием (прижать к левому краю поля);
right = 0x0004 – вывод значения с правым выравниванием (прижать к правому краю поля);
dec = 0x0010 – десятичная система счисления;
oct = 0x0020 – восьмеричная система счисления;
hex = 0x0040 – шестнадцатеричная система счисления;
showbase = 0x0080 – напечатать при выводе признак системы счисления;
showpos = 0x0400 – печатать знак числа (символ '+') при выводе положительных чисел;
Все флаги форматирования в виде отдельных фиксированных битов входят в компонент класса ios:
long x_flags;
Кроме флагов для управления форматом исп-ся следующие компонентные переменные класса ios:
int x_width – задает минимальную ширину поля вывода;
int x_precision – задает максимальное количество цифр дробной части при выводе;
int x_fill – определяет символ заполнения поля вывода до мин. ширины, определенной x_width. По умолчанию x_fill имеет значение пробела.
Пример форматирования
#include <strstream.h>
void main (){
char name[] = "Строка длиной 52 символа в поле шириной 58 позиций.";
cout.width(58); // Ширина поля вывода для потока cout.
cout.fill('$'); // Символ заполнения пустых позиций поля
cout << name << endl; // Первый вывод строки в поток cout
cout.width(58);
cout.setf (ios::left,ios::adjustfield); // Смена выравнивания
cout.fill('#'); // Символ заполнения пустых позиций поля
cout << name << endl; // Второй вывод строки в поток cout}
Результат
$$$$$$Строка длиной 52 символа в поле шириной 58 позиций.
Строка длиной 52 символа в поле шириной 58 позиций.######
Манипуляторы – специальные функции, позволяющие программисту изменять состояния и флаги потока. Особенность манипуляторов и их отличие от обычных функций состоит в том, что их имена (без параметров) и вызовы (с параметрами) можно использовать в качестве правого операнда для операции обмена (<< или >>). В качестве левого операнда в этом выражении, как обычно, используется поток (ссылка на поток), и именно на этот поток оказывает влияние манипулятор.
Манипуляторы библиотеки классов ввода-вывода языка С++ делятся на две группы: манипуляторы с параметрами и манипуляторы без параметров.
Манипуляторы без параметров:
dec/hex/oct – при вводе и выводе устанавливает флаг десятичной/ 16-й/ 8-й системы счисления;
ws – действует только при вводе и предусматривает извлечение из входного потока пробельных символов (пробел, знаки табуляции '\t' и '\v', символ перевода строки '\n', символ возврата каретки '\r', символ перевода страницы '\f');
endl – действует только при выводе, включает в выходной поток символа новой строки и сбрасывает буфер (выгружает содержимое) этого потока;
ends – действует только при выводе, включает в поток нулевой признак конца строки;
flush - действует только при выводе и очищает выходной поток, т.е. сбрасывает его буфер.
Манипулятор endl рекомендуется использовать при каждом выводе, который должен быть незамедлительно воспринят пользователем. Например, его использование просто необходимо в таком операторе: cout << "Ждите! Идет набор статистики." << endl;
При отсутствии endl здесь нельзя гарантировать, что сообщение пользователю не останется в буфере потока cout до окончания набора статистики.
Манипуляторы с параметрами определены в файле iomanip.h. Перечислим их:
setbase (int n) – устанавливает основание (n) системы счисления. Значениями могут быть: 0, 8, 10, 16.
resetiosflags (long L) – сбрасывает (очищает) отдельные флаги состояния потоков ввода и вывода в соответствии с единичными битами параметра L;
setiosflags (long L) – устанавливает отдельные флаги состояния (форматные биты) потоков ввода-вывода в соответствии с единичными битами параметра L;
setfill (int n) – устанавливает символ-заполнитель пустого пространства;
setprecision (int n) – устанавливает макс. число цифр дробной части числа при вводе и выводе;
setw (int n) – задает мин. ширину поля вывода.
Перегрузка операций << / >> для нестандартных типов данных
Каждая из операций обмена << и >> бинарная, причем левым операндом служит объект, связанный с потоком, а правый операнд должен иметь желаемый тип. Первый параметр функции – ссылка на объект потокового класса (тип istream& либо ostream&), второй параметр – ссылка или объект желаемого типа. Тип возвращаемого значения должен быть ссылкой на тот поток, для которого предназначена операция. Таким образом, формат операции-функции для перегрузки операций таков:
ostream& operator << (ostream& out, MyClass X) {
... // Любые операторы для параметра X.
out <<... // Вывод значений X.
return out; // Возврат ссылки на объект класса ostream.
}
istream& operator >> (istream& in, MyClass X) {
... // Любые операторы для параметра X.
in >>... // Ввод значений X.
return in; // Возврат ссылки на объект класса ostream.
}
Шаблоны функций и классов – параметризированные типы. Синтаксис определения шаблонов семейства функций и шаблонов семейства классов.
Шаблоны (англ. template) – средство языка C++ для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (типам данных, размерам буферов, значениям по умолчанию...). Шаблоны позволяют создавать параметризованные классы и функции.
Шаблоны классов. Например, нам нужен класс:
class MyClass { int Value; int Array[20]; ... }
Для одной конкретной цели мы можем использовать этот класс. Но если понадобится еще один класс, где нужно 30 элементов массива Array и вещественный тип Value, тогда мы можем абстрагироваться от конкретных типов и использовать шаблоны с параметрами.
Перед объявлением класса пишется слово template и указываются параметры в угловых скобках. template <int Len, typename T> class MyClass { T Value; T Array[Len];}
Тогда для первой модели пишем: SomeClass < 20, int > SomeVariable;
для второй: SomeClass < 30, double > SomeVariable2;
Пример использования
В классе, реализующем связный список целых чисел, алгоритмы добавления нового элемента списка, поиска нужного элемента не зависят от того, что элементы списка – целые числа. Те же алгоритмы применялись бы и для списка символов, строк, дат, классов игроков, и так далее.
template <class T> class List{
public: void Add (const T& Element);
bool Find (const T& Element);};
Для использования шаблона класса, необходимо указать его параметры:
List <int> li; li.Add (17);
List <string> ls; ls.Add ("Hello!");
Шаблоны функций
Шаблон функции начинается с ключевого слова template, за которым в угловых скобках следует список параметров. Затем следует объявление функции:
template <typename T> void sort (T Array[], int size);
Ключевое слово typename появилось сравнительно недавно, поэтому стандарт допускает использование class вместо typename: template < class T >
Пример использования
template <typename T> T min (T a, T b)
{ return a<b ? a : b; }
Для вызова этой функции можно просто использовать её имя:
min (1, 2); min ('a', 'b'); min (string("abc"),string("cde"));
Параметры шаблонов
Параметрами шаблонов могут быть: параметры-типы, параметры обычных типов, параметры-шаблоны.
Для параметров любого типа можно указывать значения по умолчанию.
template <class T1, // параметр-тип
typename T2, // параметр-тип