Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lucik_op.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
2.88 Mб
Скачать

Ключевое слово using как объявление

Объявление using имя::член подобно директиве, при этом оно обеспечивает более подробный уровень управления. Обычно using используется для объявления некоторого имени (из пространства имен) как принадлежащего текущей области действия (блоку).

#include <iostream.h>

namespace NAME

{ int n1=1;

int n2=2;

}

int main()

{ NAME::n1=3;

// n1=4; error 'n1' надо указывать полностью NAME::n1

// n2=5; error 'n2' : undeclared identifier

// int n2; следующая строка приводит к ошибке

using NAME::n2; // далее n2 доступно

n2=6;

cout <<NAME::n1<<" "<< n2 << endl; // результат 3 6

{ NAME::n1=7;

n2=8;

cout <<NAME::n1<<" "<< n2 << endl;// результат 7 8

}

return 1;

}

В результате выполнения программы получим:

3 6

7 8

Объявление using добавляет определенное имя в текущую область действия. В примере к переменной n2 можно обращаться без указания принадлежности классу, а для n1 необходимо полное имя. Объявление using обеспечивает более подробное управление именами, переносимыми в пространство имен. Это и есть ее основное отличие от директивы, которая переносит все имена пространства имен.

Внесение в локальную область (блок) имени, для которого выполнено явное объявление (и наоборот), является серьезной ошибкой.

Псевдоним пространства имен

Псевдоним пространства имен существует для того, чтобы назначить другое имя именованному пространству имен.

namespace spisok_name_peremen // пространство имен

{ int n1=1;

. . .

}

NAME = spisok_name_peremen; // псевдоним пространства имен

Пространству имен spisok_name_peremen назначается псевдоним NAME. В этом случае результат выполнения инструкций:

cout <<NAME::n1<< endl;

cout<< spisok_name_peremen::n1<<endl;

будет одинаков.

Организация ввода-вывода

Системы ввода-вывода С и С++ основываются на понятии потока. Поток в С++ это абстрактное понятие, относящееся к переносу информации от источника к приемнику. В языке С++ реализованы 2 иерархии классов, обеспечивающих операции ввода-вывода, базовыми классами которых являются streambuf и ios. На рис.6 приведена диаграмма классов, базовым для которых является ios (рис. 6).

В С++ используется достаточно гибкий способ выполнения операций ввода-вывода классов с помощью перегрузки операторов << (вывода) и >> (ввода). Операторы, перегружающие эти операции, обычно называют инсертером и экстрактором. Для обеспечения работы с потоками ввода-вывода необходимо включить файл iostream.h, содержащий класс iostream. Этот класс является производным от ряда классов, таких как ostream, обеспечивающего вывод данных в поток, и istream - соответственно чтения из потока. Приводимый ниже пример показывает, как можно перегрузить оператор ввода-вывода для произвольных классов.

#include "iostream.h"

class cls

{ char c;

short i;

public :

cls(char C,short I ) : c(C), i(I){}

~cls(){}

friend ostream &operator<<(ostream &,const cls);

friend istream &operator>>(istream &,cls &);

};

ostream &operator<<(ostream &out,const cls obj)

{ out << obj.c<<obj.i << endl;

return out;

}

istream &operator>>(istream &in,cls &obj)

{ in >> obj.st>>obj.i;

return in;

}

main()

{ cls s(’a’,10),ss(’ ’,0);

сout<<"abc"<<endl;

cout<<s<<ss<<endl;

cin >> ss;

return 0;

}

Общая форма функции перегрузки оператора ввода-вывода имеет вид:

istream &operator>>(istream &поток,имя_класса &объект)

ostream &operator<<(ostream &поток,const имя_класса объект)

Как видно, функция принимает в качестве аргумента и возвращает ссылку на поток. В результате доопределенный оператор можно применить последовательно к нескольким операндам

cout <<s<<ss;

Это соответствует

(cout.operator<<(a)).operator<<(b);

В приведенном примере функция operator не является компонентом класса cls, так как левым аргументом (в списке параметров) такой функции должен быть this-указатель для объекта, инициирующего перегрузку. Доступ к private-данным класса cls осуществляется через friend-функцию operator этого класса.

Рассмотрим использование перегрузки операторов << и >> для определения новых манипуляторов. Ранее мы рассмотрели использование стандартных манипуляторов форматирования выводимой информации. Однако можно определить и новые манипуляторы без изменения стандартных. В качестве примера рассмотрим переопределение манипулятора с параметрами, задающего для выводимого дробного числа ширину поля и точность.

#include<iostream.h>

class manip

{ int n,m;

ostream & (*f)(ostream&,int,int) ;

public:

manip(ostream& (*F)(ostream&,int,int), int N, int M) :

f(F), n(N), m(M) {}

friend ostream& operator<<(ostream& s, const manip& obj)

{return obj.f(s,obj.n,obj.m);}

};

ostream& f_man(ostream & s,int n,int m)

{ s.width(n);

s.flags(ios::fixed);

s.precision(m);

return s;

}

manip wp(int n,int m)

{ return manip(f_man,n,m);

}

void main(void)

{ cout<< 2.3456 << endl;

cout<<wp(8,1)<<2.3456 << endl;

}

Компонента-функция put и вывод символов

Компонента-функция ostream::put() используется для вывода одиночного символа:

char c=’a’;

. . .

cout.put(c);

Вызовы функции put() могут быть сцеплены:

cout.put(c).put(’b’).put(’\n’);

в этом случае на экран выведется буква а, затем b и далее символ новой строки.

Компоненты-функции get и getline для ввода символов.

Функция istream::get() может быть использована в нескольких вариантах.

Первый вариант – функция используется без аргументов. Вводит символ из соответствующего потока одиночный символ и возвращает его значение. Если из потока прочитан признак конца файла, то get возвращает EOF.

#include<iostream.h>

main(void)

{ char c;

cout << сin.eof()<< "вводите текст" << endl;

while((c=cin.get())!=EOF)

cout.put(c);

cout << endl<<cin.eof();

return 0; }

В программе считывается из потока cin очередной символ и выводится с помощью функции put. При считывании признака конца файла завершается цикл while. До и после цикла выводится значение cin.eof(), равное false (выводится 0) до начала цикла и true (выводится 1) после его окончания.

Второй вариант – когда функция get() используется с одним символьным аргументом. Функция возвращает false при считывании признака конца файла, иначе - ссылку на объект класса istream, для которого вызывалась функция get.

. . .

while(сin.get(с))

cout.put(c);

. . .

При третьем варианте функция get() принимает три параметра: указатель на символьный массив (строку), максимальное число символов и ограничитель ввода (по умолчанию ’\n’). Ввод прекращается, когда считано число символов на один меньшее максимального или считан символ-ограничитель. При этом в вводимую строку добавляется нуль-символ. Символ-ограничитель из входного потока не удаляется, это при повторном вызове функции get приведет к формированию пустой строки.

сhar s[30];

. . .

сin.get(s,20)) // аналогично cin.get(s,20,’\n’)

cout<<s<<endl;

. . .

Функция isteram::getline() действует аналогично функции get() с тремя параметрами с тем отличием, что символ-ограничитель удаляется из входного потока.

Ниже коротко рассмотрены другие функции-компоненты класса istream.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]