Программирование
Шаблоны. Потоки ввода-вывода
Шаблоны
Шаблоны. Родовые функции
Шаблоны. Родовые функции
Шаблоны. Родовые функции
Шаблоны. Родовые функции
Шаблоны. Родовые классы
Шаблоны. Родовые классы
Потоки ввода-вывода
Потоки ввода-вывода
Файловые потоки ввода-вывода
Конструирование объекта потока
Конструирование объекта потока
1.18M
Category: programmingprogramming

Программирование. Потоки ввода - вывода

1. Программирование

Лекция 13

2. Шаблоны. Потоки ввода-вывода

1. Шаблоны. Родовые функции
2. Шаблоны. Родовые классы.
3. Потоки ввода-вывода.
4. Файловые потоки ввода-вывода.

3. Шаблоны

• С помощью шаблонов можно создавать
родовые функции и родовые классы.
• В шаблонах тип обрабатываемых данных
задается как параметр (заранее не известен).
Это позволяет использовать одну и ту же
функцию или класс с разными типами
данных.

4. Шаблоны. Родовые функции

• Родовые функции определяют базовый набор
операций, которые будут применяться к
разным типам данных.
• При вызове родовая функция будет работать с
тем типом данных, который она получит как
параметр.
• Родовая функция позволяет определить
сущность некоторого алгоритма обработки
данных без привязки к конкретному типу
данных.

5. Шаблоны. Родовые функции

• Родовая функция создается с помощью ключевого
слова template и называется шаблоном
функции.
• Формат определения шаблона:
template <class T>
тип_возвр_знач имя_функции (список_парам)
{ тело_функции }
• T – это фиктивное имя типа данных (родовый тип
данных), который компилятор автоматически
заменяет именем реального типа данных при
создании конкретного варианта функции.

6.

template <class T> void Swap(T& a, T& b) {
T t;
t = a; a = b; b = t;
}

7.

template <class T> void Swap(T& a, T& b) {
T t;
t = a; a = b; b = t;
}
int main() {
int i = 10, j = 20;
float x = 10.1, y = 20.2;
cout
cout
cout
cout
<<
<<
<<
<<
"Before swap:" << endl;
"i = " << i << ", j = " << j << endl;
"x = " << x << ", y = " << y << endl;
endl;
Swap(i, j);
Swap(x, y);
cout << "After swap:" << endl;
cout << "i = " << i << ", j = " << j << endl;
cout << "x = " << x << ", y = " << y << endl;
return 0;
}

8.

template <class T> void Swap(T& a, T& b) {
T t;
t = a; a = b; b = t;
}

9. Шаблоны. Родовые функции

• Вместо ключевого слова class можно
использовать typename.
• Можно использовать несколько родовых типов
данных:
template <class T1, class T2>
тип_возвр_знач имя_функции (список_парам)
{ тело_функции }
• Родовые функции похожи на перегруженные
функции. Но при перегрузке функций можно
написать разные алгоритмы, а родовая функция
определяет общий алгоритм.

10. Шаблоны. Родовые функции

template <typename T1, typename T2>
void print(T1 x, T2 y) {
cout << x << ' ' << y << endl;
}
int main() {
print(10, "hi");
print(0.2, 0x10000);
print('a', 1.5);
print(12, 5);
return 0;
}

11. Шаблоны. Родовые классы

• Родовые классы содержат общую логику хранения
и обработки данных, которую можно применять к
объектам разного типа.
• Формат объявления шаблона класса:
template <typename T>
class имя_класса {
тело_класса
};
• T – имя фиктивного типа данных. Конкретный тип
будет определен при создании объекта класса.

12. Шаблоны. Родовые классы

• Определение функций класса вне шаблона:
template <class T>
тип_возвр_знач имя_класса <T> ::
имя_функции (список_парам) {тело_функции }
• Функции-элементы родового класса
автоматически становятся родовыми
функциями.
• Создание объекта класса на основе шаблона:
имя_класса <тип_данных> имя_объекта;

13.

template <typename T>
class List {
T data;
List* next;
public:
List(T d);
void add(List* node) {
node -> next = this;
next = 0;
}
List* getNext() { return next; }
T getData() { return data; }
};
template <typename T>
List<T>::List(T d) {
data = d;
next = 0;
}

14.

int main() {
List<char> start('a');
List<char> *p, *last;
last = &start;
for(int i = 1; i < 26; i++) {
p = new List <char> ('a'+i);
p -> add(last);
last = p;
}
p = &start;
while(p) {
cout << p -> getData();
p = p -> getNext();
}
cout << endl;
return 0;
}

15.

16.

class Point {
float x, y;
public:
Point(float x = 0.0, float y = 0.0) {
this -> x = x;
this -> y = y;
}
friend ostream& operator<< (ostream& out, Point& p);
};
ostream& operator<< (ostream& out, Point& p) {
out << '[' << p.x << ',' << p.y << ']' << endl;
return out;
}

17.

int main() {
List<Point> start(Point(0, 0));
List<Point> *p, *last;
last = &start;
for(int i = 1; i < 26; i++) {
p = new List <Point> (Point(i/2.0, i));
p -> add(last);
last = p;
}
p = &start;
while(p) {
cout << p -> getData();
p = p -> getNext();
}
cout << endl;
return 0;
}

18.

19. Потоки ввода-вывода

• В C++ имеется набор классов для управления
вводом-выводом, использующий механизм
перегрузки операций.
• Классы потоков:
• ios – базовый класс ввода-вывода;
• istream и ostream – потоки ввода и вывода
соответственно, производные от ios;
• iostream – комбинированный класс для ввода и
вывода, производный от istream и ostream;
• ifstream, ofstream, fstream – классы для
управления файловым вводом-выводом.

20. Потоки ввода-вывода

• Предопределенные объекты-потоки:
Имя
Класс
Описание
cin
istream
Стандартный поток ввода (клавиатура)
cout
ostream
Стандартный поток вывода (экран)
cerr
ostream
Стандартное устройство для вывода
ошибок без буферизации (экран)
clog
ostream
Стандартное устройство для вывода
ошибок с буферизацией (экран)

21.

class Point {
float x, y;
public:
Point(float x = 0.0, float y = 0.0) {
this -> x = x;
this -> y = y;
}
friend ostream& operator << (ostream& out, Point& p);
friend istream& operator >> (istream& in, Point& p);
};
ostream& operator << (ostream& out, Point& p) {
out << '[' << p.x << ',' << p.y << ']' << endl;
return out;
}
istream& operator >> (istream& in, Point& p) {
in >> p.x >> p.y;
return in;
}

22.

int main() {
Point p;
cout << "Enter point coordinates: ";
cin >> p;
cout << "The point: " << p;
return 0;
}

23.

istream& operator >> (istream& in, Point& p) {
char c;
in >> c;
if(c != '[') return in;
in >> p.x;
in >> c;
if(c != ',') return in;
in >> p.y;
in >> c;
return in;
}

24. Файловые потоки ввода-вывода

• ifstream, ofstream, fstream – классы для
управления файловым вводом-выводом.
• Чтобы работать с файловым потоком, нужен
объект потока и открытый файл, связанный с
ним.
• Для закрытия файла нужно вызвать метод
close() для объекта потока.
• Деструктор потока автоматически закрывает
файл при уничтожении объекта потока.

25. Конструирование объекта потока

• Конструктор, создающий объект без открытия файла:
ifstream();
ofstream(); fstream();
• Конструктор, открывающий указанный файл и связывающий его с
потоком:
ifstream(const char* name,
int mode = ios::in,
long prot = 0666);
• Конструктор, создающий объект и связывающий его с открытым
файлом:
ifstream(int file);
• Конструктор, создающий объект и связывающий его с открытым
файлом и буфером:
ifstream(int file, char* buf, int len);

26. Конструирование объекта потока

• Режимы открытия файла (параметр mode):
ifstream(const char* name, int mode, long prot);
• Значения параметра определены в классе ios:
Константа
Описание
app
Открытие для записи в конец файла
ate
При открытии указатель позиционируется на конец файла
binary
Файл открывается в двоичном режиме
in
Файл открывается для ввода
out
Файл открывается для вывода
trunc
Если файл существует, его содержимое теряется
• Параметры можно комбинировать с помощью
поразрядного «ИЛИ»

27.

#include <iostream>
#include <fstream>
using namespace std;
class Point {
float x, y;
public:
Point(float x = 0.0, float y = 0.0);
friend ostream& operator << (ostream& out, Point& p);
friend istream& operator >> (istream& in, Point& p);
friend ofstream& operator << (ofstream& out, Point& p);
friend ifstream& operator >> (ifstream& in, Point& p);
};

28.

ofstream& operator << (ofstream& out, Point& p) {
out << '[' << p.x << ',' << p.y << ']' << endl;
return out;
}
ifstream& operator >> (ifstream& in, Point& p) {
char c;
in >> c;
if(c != '[') return in;
in >> p.x;
in >> c;
if(c != ',') return in;
in >> p.y;
in >> c;
return in;
}

29.

int main() {
Point p;
cout << "Enter point coordinates: ";
cin >> p;
char fileName[] = "points.txt";
fstream fs(fileName, ios::app|ios::binary);
fs << p;
fs.close();
fs.open(fileName, ios::in|ios::binary);
while(fs) {
fs >> p;
if(fs) cout << "The point: " << p;
}
fs.close();
return 0;
}
English     Русский Rules