Язык Си++ предоставляет возможность использования 2-х способов организации ввода данных встроенных типов.
1-ый способ. Использование средств Си. В этом случае используются библиотечные функции ввода-вывода. Одним из фактических параметров, которые необходимо задавать при вызове этих функций является фактический параметр, который задает сведения о форматах, используемом при вводе-выводе. Структура этого параметра является достаточно громоздкой и обычно имеет большое количество ошибок. Кроме того, существуют определенные правила, по которым задаются адреса данных. Например, при вводе требуется задавать адреса данных. Невыполнение этого требования приводит также к ошибкам, поиск которых также является достаточно сложным.
2-ой способ. В этом случае для организации ввода-вывода созданы стандартные объекты cin (для ввода) класса istream и cout(для вывода) класса ostream. В этих классах для каждого встроенного типа данных определена собственная функция ввода или вывода. Отличие от первого способа заключается в том, что эти функции представлены функциями, которые перегружают 2 встроенные операций сдвига <<(вывод) и >>(ввод). То есть, в этом случае используются функции operator<<(вывод) и operator>>(ввод). При этом, как и в других случаях перегрузки, транслятор использует вызов той перегруженной функции, которая совпадает по типу фактического параметра.
Например, ввод целого числа а, строки s символов записывается как
сin>>a>>>s; // в одной строке указаны данные разных типов
Транслятор это выражение интерпретирует как
(cin.operator>>(a)).operator>>(s)
где cin - стандартный объект, для которого определены функции-operator>> по каждому встроенному типу данных. В самом операторе ввода не требуется указывать тип данных, транслятор определяет его из описания.
Например, вывод целого числа а, строки “hhhhh” s записывается как
cout<<a<<”hhhhh”<<a; //// в одной строке указаны данные разных типов
Транслятор это выражение интерпретирует как
(сout.operator<<(a)).operator<<(s)
где cout – стандартный объект, для которого определены функции-operator << по каждому встроенному типу данных. В самом операторе вывода также не требуется указывать тип данных, транслятор определяет его из описания.
При организации ввода-вывода объектов, также возможно использование двух способов.
1-ый способ. Использование специальных член-функций ввода-вывода, которые вызываются для каждого объекта обычным способом и используют стандартные средства вывода встроенных типов.
2-ой способ. Желательно обеспечить ввод-вывод объектов по 2-ому способу, который используется для встроенных типов; при этом также необходимо, чтобы в одной строке оператора можно было бы указывать данные разных типов, включая объекты.
При реализации этого способа необходимо выполнить следующую последовательность действий.
1.- перегрузить соответствующую операцию сдвига (<< или >>) для класса, который описывает объект.
Для этого в этом классе должна быть объявлена дружественная функция operator << или operator >> с двумя параметрами.
1-ый параметр указывает имя формального параметра, который задает стандартный объект, используемый в операторах ввода-вывода оператора функции operator;
2- ой параметр задает имя формального параметра, который задает имя и тип объекта, для которого выполняется дружественная функция.
Функция operator должна возвращать ссылку на объект, представленный 1-ым параметром для того, чтобы можно было бы записывать операции ввода-вывода в одну строку.
Дружественная функция operator описывается вне класса как обычная функция. В ней описываются алгоритм ввода членов-данных объекта с любыми видами обработки.
1-ый пример
Эта программа представляет пример переопределения встроенной операции сдвига << языка СИ++ для вывода членов-данных объектов определенного класса: строки и длины строки.
Эта перегруженная операция используется в одной строке вывода с операцией вывода строки, которая представляет данные встроенного типа.
*#include <string.h>
#include <iostream.h>
#include <conio.h>
class y // заголовок класса
{ int n; // длина строки
char *s; // указатель строки
friend ostream& operator <<(ostream& , y); /* объявление дружественной функции-оператора << для класса y */
public:
y(char* s1) // конструктор
{ n=strlen(s1);
s=new char [n+1]; // запрос памяти для строки
strcpy(s,s1);}
};// конец определения класса
/* перегруженная операция вывода данных объекта класса y; дружественная функция*/
ostream& operator<<(ostream& r, y h)
{ return r<<"lenght of string "<<h.n<<" string "<<h.s<<endl;};
int main()// главная функция
{ clrscr();
y iop ("ggggg"); // определение объекта iop класса y
cout<<"output "<<iop<<'\n';/*вывод строки "output"и содержимого объекта iop*/
getche();
return 0;
}
Замечание
При реализации оператора cout<<"output "<<iop<<'\n', записанного в программе, на самом деле выполняется последовательностью сцепленных операторов operator((cout.operator<<(“output”)),iop).operator(‘\n’);
В этом случае для вывода строки “output” выполняется оператор cout.operator<<(“output”);
Для вывода объекта iop выполняется оператор operator<<(cout,iop); где формальному параметру r соответствует фактический параметр cout, который задает имя стандартного объекта вывода.
В этом случае для вывода символа ‘\n’ выполняется оператор cout.operator<<('\n').
2-ой пример
Программа этого примера использует условие предыдущего примера; отличие состоит в том, что операция вывода переопределена не для одного объекта, а для массива объектов. Поэтому имеется возможность выводить в одной строке не отдельные элементы, а сразу весь массив.(но с одним и тем же размером массива).
#include <string.h>
#include <iostream.h>
#include <conio.h>
class y
{ int n;
char *s;
friend ostream& operator <<(ostream& , y*);// объявление дружественной функции
public: //конструктор
y(char* s1)
{ n=strlen(s1);
s=new char [n+1];
strcpy(s,s1);}
};// конец определения класса
// переопределенная операция << вывода массива объектов
ostream& operator<<(ostream& r, y* h)
{ for (int i=0;i<2; i++)
{r<<"lenght of string "<<((h+i)->n)<<" string "<<(h+i)->s<<endl;};
return r;}
int main()// главная функция
{ clrscr();
y iop[2]={y("ggggg"),y("uuuuuuu")}; /* инициализация массива из 2-х объектов*/
cout<<"output \n "<<iop<<'\n'; // вывод строки и массива двух объектов
getche();
return 0;
}
3- ий пример
В дополнение к предыдущему примеру в программе этого примера переопределяется для объекта той же структуры встроенная операция >> для ввода данных объекта. В переопределенной функции реализуется ввод данных в промежуточный буфер и далее передача веденных данных в объект; в основной программе обращение к этой операции производится для каждого элемента определенного массива объектов. Отличительной особенностью является то, что 2-ой аргумент у переопределяющей функции ввода operator >> задается ссылкой, так как при вводе должно быть выполнено изменение данных, т.е. должен быть передан адрес.
#include <string.h>
#include <iostream.h>
#include <conio.h>
class y // заголовок класса y
{ int n;
char *s;
// объявление 2-х дружественных функций для ввода и вывода данных
friend ostream& operator <<(ostream& , y);
friend istream& operator >>(istream& , y&);
public:
//конструктор
y(char* s1)
{ n=strlen(s1)+1;
s=new char [n];
strcpy(s,s1);}
};// конец определения класса
//переопределение операции вывода объекта
ostream& operator<<(ostream& r, y h)
{ r<<"lenght of string "<<((h.n)-1)<<" string "<<h.s<<endl;
return r;}
// переопределение операции ввода объекта
istream& operator>>(istream& r, y& h)
{ char buf[255];
cout <<"vvedite stroku \n";
r>>buf;
h.n=strlen(buf)+1;
h.s=new char [h.n];
strcpy(h.s,buf);
return r;}
// основная программа для ввода и вывода объектов с использованием
//перегруженных операций ввода и вывода
int main()
{ clrscr();
y iop[2]={y("ggggg"),y("uuuuuuu")};//инициализация массива объектов
for (int i=0; i<2; i++)
cout<<"output \n "<<iop[i]<<'\n';// вывод i-го объекта
cout<<"vvedite obekti \n";
for ( i=0; i<2; i++)
cin>>iop[i]; //ввод i-го объекта
for ( i=0; i<2; i++)
cout<<"output \n "<<iop[i]<<'\n'; // вывод i-го объекта
getche();
return 0;
}
2. Индивидуальные задания
Разработать 6 программ обработки набора объектов. Все программы должны реализовать единый алгоритм обработки, указанный в разделе варианты заданий темы № 1.
Для каждого объекта задана характеристика: данные и функции, которые могут обрабатывать эти данные. В индивидуальном задании эти характеристики соответственно указаны в пунктах: исходные данные и функции.
Программы 2-6 отличаются используемыми программными средствами, которые определены в каждой теме.
Дата: 2019-03-05, просмотров: 239.