В. С. Романчик, А. Е. Люлькин
С++
ЛАБОРАТОРНЫЕ РАБОТЫ
по курсу «МЕТОДЫ ПРОГРАММИРОВАНИЯ»
Учебно-методическое пособие
Для студентов механико-математического факультета
МИНСК
БГУ
УДК 681.142.2(072)
ББК 32.973.26-018.1я73
Р69
А в т о р ы:
В. С. Романчик, А. Е. Люлькин
Р е ц е н з е н т ы:
кандидат физико-математических наук, доцент Галкин И. М.,
кандидат физико-математических наук, доцент, Суздаль С. В.
Рекомендовано Ученым советом механико-математического факультета БГУ
29 марта 2005 года, протокол № ___
В пособии рассматриваются шесть лабораторных работ, выполняемых студентами 2-го курса при изучении вопросов, связанных с программированием на языке C++. Эти вопросы являются составной частью курса “Методы программирования”, изучаемого студентами 1-го – 2-го курсов механико-математического факультета. Для выполнения каждого задания отводится 2-3 недели. Для выполнения всех заданий отводится 14 недель.
УДК 681.142.2(072)
ББК 32.973.26-018.1я73
ã Коллектив авторов, 2005
ã БГУ, 2005
Лабораторная работа № 1 Тема. Простейшие классы и объекты
Теоретическое введение. Классы представляют абстрактные типы данных с открытым интерфейсом и скрытой внутренней реализацией. В классах реализованы базовые принципы объектно-ориентированного программирования (ООП):
1) абстракция данных;
2) инкапсуляция – в классах объединяются данные и методы (функции) для работы с ними, так как лишь через методы возможен доступ к сокрытым данным класса;
3) наследование – в производных классах наследуются члены базового класса;
4) полиморфизм – возможность использования одних и тех же методов для работы с различными объектами базового и порожденных им классов.
Определение простейшего класса без наследования имеет вид:
class имя_класса {
По умолчанию раздел private – частные члены класса
Public: // открытые функции и переменные класса
};
Имя класса является новым типом данных. Понятию переменной данного типа соответствует понятие объекта класса. Список членов класса включает описание данных и функций. Функции, описания которых находятся в определении класса, называются функциями-членами класса.
Переменные и функции, объявленные в разделе класса по умолчанию или явно как private, имеют область видимости в пределах класса. Их можно сделать видимыми вне класса, если объявить в разделе public:. Обычно переменные объявляются в разделе private, а функции в разделе public.
Классами в С++ являются также структуры (struct) и объединения (union). В отличие от класса члены структуры по умолчанию являются открытыми, а не закрытыми. Кроме того, объединения не могут наследоваться и наследовать.
При реализации функциональной части класса могут быть использованы функции-члены класса, конструкторы, деструкторы, функции-операторы. Функции класса всегда объявляются внутри класса. Определение функции может находиться и внутри класса. Такие функции называются inline -функциями. Обычно определения функций-членов класса помещаются вне класса. При этом перед именем функции указывается имя_класса::.
тип имя_класса:: имя_функции (описание аргументов)
{ /*тело функции*/ }
Вызов функций осуществляется одним из двух способов:
имя_объекта.имя_функции(аргументы);
указатель_на_объект -> имя_функции(аргументы);
Обращение к данным объекта класса осуществляется с помощью функций, вызываемых из объектов. При этом функции-члену класса передается скрытый указатель this на объект, вызывающий функцию.
Функции-«друзья» класса, объявляемые в классе со спецификатором friend, указатель this не содержат. Объекты, с которыми работают такие функции, должны передаваться в качестве их аргументов. Это обычные функции языка С++, которым разрешен доступ к закрытым членам класса.
Пример.
/* Создается класс Student. Формируется динамический массив объектов. При тестировании выводится: сформированный список студентов, список студентов заданного факультета, список студентов для заданных факультета и курса.*/
#include <conio.h>
#include <string.h>
#include <iostream.h>
struct date // дата рождения
{char daymon[6];
int year; };
//======= class Student =================
class Student{
char name[30]; //private
date t;
char adr[30], fac[20];
int kurs;
public:
Student();
char *getfac();
int getkurs();
void show();
};
Student::Student()
{cout<<"Input name:"; cin>>name;
cout<<"Input date of born\n";
cout<<"Day.mon:"; cin>>t.daymon;
cout<<"Year:"; cin>>t.year;
cout<<"Input adr:"; cin>>adr;
cout<<"Input fac:"; cin>>fac;
cout<<"Input kurs:"; cin>>kurs;
}
void Student::show()
{
cout<<"Name:"<<name<<endl;
cout<<"Was born:"<<t.daymon<<'.'<<t.year<<endl;
cout<<"Address:"<<adr<<endl;
cout<<"Fac:"<<fac<<endl;
cout<<"Kurs:"<<kurs<<endl;
}
char *Student::getfac() { return fac; }
int Student::getkurs() { return kurs; }
void spisfac(Student spis[],int n)//список студентов заданного факультетата
{char fac[20];
cout<<"Input faculty:"; cin>>fac;
for(int i=0;i<n;i++)
if(strcmp(spis[i].getfac(),fac)==0)spis[i].show();
}
void spisfackurs(Student spis[],int n)
//список студентов заданных факультета и курса
{int i,k;
char fac[20];
cout<<"Input faculty:"; cin>>fac;
cout<<"Input the course:"; cin>>k;
for(i=0;i<n;i++)
if ((strcmp(spis[i].getfac(),fac)==0)&&(spis[i].getkurs()==k))
spis[i].show();
}
//========= main ================
void main()
{ Student *spis;
int n;
cout<<"Input a number of students: "; cin>>n;
spis=new Student [n];
for(int i=0;i<n;i++) {
cout<<"=============================="<<endl;
spis[i].show();
}
spisfac(spis,n);
spisfackurs(spis,n);
delete [] spis;
cout<<"press any key!"
while(!kbhit());
}
Задания для самостоятельного решения
Разработать классы для описанных ниже объектов. Включить в класс методы set (…), get (…), show (…). Определить другие методы.
1. Student: Фамилия, Имя, Отчество, Дата рождения, Адрес, Телефон, Факультет, Курс. Создать массив объектов. Вывести:
а) список студентов заданного факультета;
б) списки студентов для каждого факультета и курса;
в) список студентов, родившихся после заданного года.
2. Abiturient: Фамилия, Имя, Отчество, Адрес, Оценки. Создать массив объектов. Вывести:
а) список абитуриентов, имеющих неудовлетворительные оценки;
б) список абитуриентов, сумма баллов у которых не меньше заданной;
в) выбрать N абитуриентов, имеющих самую высокую сумму баллов, и список абитуриентов, имеющих полупроходной балл.
3. Aeroflot: Пункт назначения, Номер рейса, Тип самолета, Время вылета, Дни недели. Создать массив объектов. Вывести:
а) список рейсов для заданного пункта назначения;
б) список рейсов для заданного дня недели;
в) список рейсов для заданного дня недели, время вылета для которых больше заданного.
4. Book: Автор, Название, Издательство, Год, Количество страниц. Создать массив объектов. Вывести:
а) список книг заданного автора;
б) список книг, выпущенных заданным издательством;
в) список книг, выпущенных после заданного года.
5. Worker: Фамилия и инициалы, Должность, Год поступления на работу, Зарплата. Создать массив объектов. Вывести:
а) список работников, стаж работы которых на данном предприятии превышает заданное число лет;
б) список работников, зарплата которых больше заданной;
в) список работников, занимающих заданную должность.
6. Train: Пункт назначения, Номер поезда, Время отправления, Число общих мест, Купейных, Плацкартных. Создать массив объектов. Вывести:
а) список поездов, следующих до заданного пункта назначения;
б) список поездов, следующих до заданного пункта назначения и отправляющихся после заданного часа;
в) список поездов, отправляющихся до заданного пункта назначения и имеющих общие места.
7. Product: Наименование, Производитель, Цена, Срок хранения, Количество. Создать массив объектов. Вывести:
а) список товаров для заданного наименования;
б) список товаров для заданного наименования, цена которых не превышает указанной;
в) список товаров, срок хранения которых больше заданного.
8. Patient: Фамилия, Имя, Отчество, Адрес, Номер медицинской карты, Диагноз. Создать массив объектов. Вывести:
а) список пациентов, имеющих данный диагноз;
б) список пациентов, номер медицинской карты которых находится в заданном интервале.
9. Bus: Фамилия и инициалы водителя, Номер автобуса, Номер маршрута, Марка, Год начала эксплуатации, Пробег. Создать массив объектов. Вывести:
а) список автобусов для заданного номера маршрута;
б) список автобусов, которые эксплуатируются больше 10 лет;
в) список автобусов, пробег у которых больше 10 000 км.
10. Customer: Фамилия, Имя, Отчество, Адрес, Телефон, Номер кредитной карточки, Номер банковского счета. Создать массив объектов. Вывести:
а) список покупателей в алфавитном порядке;
б) список покупателей, номер кредитной карточки которых находится в заданном интервале.
11. File: Имя файла, Размер, Дата создания, Количество обращений. Создать массив объектов. Вывести:
а) список файлов, упорядоченный в алфавитном порядке;
б) список файлов, размер которых превышает заданный;
в) список файлов, число обращений к которым превышает заданное.
12. Word: Слово, Номера страниц, на которых слово встречается (от 1 до 10), Число страниц. Создать массив объектов. Вывести:
а) слова, которые встречаются более чем на N страницах;
б) слова в алфавитном порядке;
в) для заданного слова номера страниц, на которых оно встречается.
13. House: Адрес, Этаж, Количество комнат, Площадь. Создать массив объектов. Вывести:
а) список квартир, имеющих заданное число комнат;
б) список квартир, имеющих заданное число комнат и расположенных на этаже, который находится в определенном промежутке;
в) список квартир, имеющих площадь, превосходящую заданную.
14. Phone: Фамилия, Имя, Отчество, Адрес, Номер, Время внутригородских разговоров, Время междугородних разговоров. Создать массив объектов. Вывести:
а) сведения об абонентах, время внутригородских разговоров которых превышает заданное;
б) сведения об абонентах, воспользовавшихся междугородней связью;
в) сведения об абонентах, выведенные в алфавитном порядке.
15. Person: Фамилия, Имя, Отчество, Адрес, Пол, Образование, Год рождения. Создать массив объектов. Вывести:
а) список граждан, возраст которых превышает заданный;
б) список граждан с высшим образованием;
в) список граждан мужского пола.
Тесты
1. Для чего нужны классы?
Варианты ответа*:
*1) для определения новых типов в программе; 2) для упрощения работы с функциями; *3) для соединения данных и операций над ними; 4) для упрощения работы с указателями.
2. Методы класса определяют:
*1) какие операции можно выполнять с объектами данного класса; 2) какие типы значений могут принимать данные-члены класса; 3) каким образом реализуется защита данных-членов класса.
3. Атрибуты (данные-члены) класса могут быть:
1) только целыми числами; 2) любыми встроенными типами; *3) любого определенного в программе типа.
4. Какая из записей соответствует обращению к атрибуту arg класса А в определении метода этого же класса?
Варианты ответа:
*1) this –> arg; *2) arg; 3) A –> arg; 4) A –> this –> arg.
5. Если имеется код
class A {public: int a; }; A *obj;
то как обратиться к переменной а?
Варианты ответа:
1) obj.a; 2) (*obj) –> a; *3) obj –> a; 5) obj:: a.
6. Если имеется код
class A {public: int a, b, c;}; A *obj;
то как обратиться к переменной b?
Варианты ответа:
1) (*obj) –> b; 2) A:: b; *3) (*obj).b; 4) obj –> a.b.
* Звездочкой в тестах отмечены правильные ответы.
7. Каков будет результат выполнения следующего кода:
class A {
public:
int inc (int x) {return x++;}
int inc (short x) (return x+2;}
};
A obj; int y=5;
cout << obj.inc(y);?
Варианты ответа:
*1) 5; 2) 6; 3) 7; 4) ошибка при компиляции.
8. Каков будет результат выполнения следующего кода:
class A {
public:
int y;
int inc (int x) {return y++;}
int inc (short x) {return x+y;}
};
A obj; int y=5; obj.y= 6;
cout << obj.inc(y);?
Варианты ответа:
1) 5; *2) 6; 3) 11; 4) 7; 5) ошибка при компиляции.
9. Какими по умолчанию объявляются элементы структуры?
Варианты ответа:
1) private; *2) public; 3) protected; 4) по умолчанию не объявляются.
Лабораторная работа № 2 Тема. Разработка классов
Теоретическое введение. При разработке класса необходимо определить данные класса и его методы, конструкторы и деструкторы. Конструктор – это функция-член класса, которая вызывается автоматически при создании статического или динамического объекта класса. Он инициализирует объект и переменные класса. У конструктора нет возвращаемого значения, но он может иметь аргументы и быть перегружаемым.
Противоположные конструктору действия выполняет деструктор, который вызывается автоматически при уничтожении объекта. Деструктор имеет то же имя, что и класс, но перед ним стоит ‘~’. Деструктор можно вызывать явно в отличие от конструктора. Конструкторы и деструкторы не наследуются, хотя производный класс может вызывать конструктор базового класса.
Операторы-функции. Используются для введения операций над объектами, связываемых с символами:
+, -, *, /, %, ^, &, |, ~,!, =, <, >,+=, [], ->, (), new, delete.
Оператор-функция является членом класса или дружественной (friend) классу. Общая форма оператор-функции-члена класса:
возвращаемый_тип имя_класса::operator#(список_аргум)
{/*тело функции*/}
После этого вместо operator#(a,b) можно писать a#b. Здесь # представляет один из введенных выше символов. Примерами являются операторы >> и << – перегружаемые операторы ввода-вывода. Отметим, что при перегрузке нельзя менять приоритет операторов и число операндов. Если оператор-функция-член класса перегружает бинарный оператор, то у функции будет только один параметр-объект, стоящий справа от знака оператора. Объект слева вызывает оператор-функцию и передается неявно с помощью указателя this. В дружественную функцию указатель this не передается, поэтому унарный оператор имеет один параметр, а бинарный – два.
Оператор присваивания не может быть дружественной функцией, а только членом класса.
Пример. Создается класс Polynom. В головной программе выполняется тестирование класса.
#include <iostream.h>
#include <conio.h>
#include <math.h>
class Polynom {
int n;
double *koef;
public:
Polynom(); //конструкторы
Polynom(int k);
Polynom(int k,double *mas);
Polynom(const Polynom&ob); //конструктор копирования
~Polynom(){delete[]koef;}
void GiveMemory(int k);
void SetPolynom(int k,double *mas);
void SetDegree(int k){n=k;}; //установить степень
void CalculateValue(double x); //вычислить значение
int GetDegree(){return n;}; //получить степень
double GetOneCoefficient(int i){return(koef[i]);};
Polynom operator+(Polynom ob); //перегрузка операторов
Polynom operator*(Polynom ob);
double& operator[](int i){return(koef[i]);}//перегрузка []
Polynom& operator = (const Polynom p) {
if(&p==this) return *this;
if(koef) delete [] koef;
n=p.n;
koef=new double [p.n+1];
for(int i=0;i<=p.n;i++)
koef[i]=p.koef[i];
return *this;
}
friend ostream& operator<<(ostream& mystream,Polynom &ob);
friend istream& operator>>(istream& mystream,Polynom &ob);
int min(int n,int m)
{return (n<m)? n:m; }
int max(int n,int m)
{return (n>m)? n:m; }
};
//*********** Polynom() **********************************
Polynom::Polynom()
{ randomize();
n=random(5);
koef=new double[n+1];
if(!koef){cout<<"Error";getch();return;}
for(int i=n;i>=0;i--)
koef[i]=random(10)-5;
}
//************* Polynom(int k) *******************************
Polynom::Polynom(int k)
{ n=k;
koef=new double[n+1];
if(!koef){cout<<"Error";getch();return;}
for(int i=n;i>=0;i--)
koef[i]=random(10)-5;
}
//****************** Polynom(int k,double mas[]) ******************
Polynom::Polynom(int k,double mas[])
{n=k;
koef=new double[n+1];
if(!koef){cout<<"Error";getch();return;}
for(int i=n;i>=0;i--)
koef[i]=mas[i];
}
//*************** Polynom(const Polynom&ob) *********************
Polynom::Polynom(const Polynom&ob)
{n=ob.n;
koef=new double[n+1];
if(!koef){cout<<"Error";getch();return;}
for(int i=0;i<=n;i++)
koef[i]=ob.koef[i];
}
//**************** void GiveMemory(int k) **********************
void Polynom::GiveMemory(int k)
{
if(koef) delete [] koef;
koef=new double[k+1];
if(!koef){cout<<"Error";getch();return;}
}
//******************** SetPolynom **************************
void Polynom::SetPolynom(int k,double *mas)
{ n=k;
if(koef) delete [] koef;
koef = new double [n+1];
for(int i=n;i>=0;i--)
koef[i]=mas[i];
}
//*************** CalculateValue *****************************
void Polynom::CalculateValue(double x=1.0)
{ double s;
int i;
for(s=koef[0],i=1;i<=n;i++)
s=s+koef[i]*pow(x,i);
cout<<"f("<<x<<")="; cout<<s<<endl;
}
//**************** Polynom operator+(Polynom ob) ***************
Polynom Polynom::operator+(Polynom ob)
{ int i;
Polynom rab;
rab.GiveMemory(max(n,ob.GetDegree()));
for(i=0;i<=min(n,ob.GetDegree());i++)
rab.koef[i]=koef[i]+ob.GetOneCoefficient(i);
if(n<ob.GetDegree())
{
for(i=min(n,ob.GetDegree())+1;i<=ob.GetDegree();i++)
rab.koef[i]=ob.GetOneCoefficient(i);
rab.n=ob.GetDegree();
}
else
{
for(i=min(n,ob.GetDegree())+1;i<=n;i++) rab.koef[i]=koef[i];
rab.n=n;
}
return rab;
}
//*************** Polynom operator*(Polynom ob) ***************
Polynom Polynom::operator*(Polynom ob)
{
int i,j,k;
double s;
Polynom rab;
rab.GiveMemory(n+ob.GetDegree());
for(i=0;i<=n+ob.GetDegree();i++)
{ s=0;
for(j=0;j<=n;j++)
for(k=0;k<=ob.GetDegree();k++)
if(j+k==i)s=s+koef[j]*ob.GetOneCoefficient(k);
rab.koef[i]=s;
}
rab.n=n+ob.GetDegree();
return rab;
}
//********** ostream& operator<<(ostream& mystream,Polynom &ob) ******
ostream& operator<<(ostream& mystream,Polynom &ob)
{ char c=' '; //пропустим “+” перед первым коэффициентом
for(int i=ob.n;i>=0;i--)
{ double ai=ob.koef[i];
if(ai==0) continue;
else {if(ai>0) mystream<<c; mystream<<ai;}
if(i==0) continue; else mystream<<"x";
if(i==1) continue; else mystream<<"^"<<i;
if(ai!=0)c='+';
}
if(c==' ')mystream<<0;
mystream<<endl;
return mystream;
}
//********* istream& operator>>(istream& mystream,Polynom &ob) *
istream& operator>>(istream& mystream,Polynom &ob)
{
int i;
cout<<"Enter Degree:"; mystream>>ob.n; cout<<endl;
for(i=ob.n;i>=0;i--)
{
cout<<"Enter koeff "<<i<<":"; mystream>>ob.koef[i];
}
return mystream;
}
//******************** MAIN ****************************
int main(int argc, char* argv[])
{ const int m=3;
Polynom f,g,masp[m],*p1,s;
int n=5,i;
double K[6]={1.0,3.2,0.0,4.1,0.0,1.1};
p1=new Polynom(n,K);
cout<<*p1;
p1->CalculateValue(2.0);
cin>>f;
cout<<" f(x)= "; cout<<f;
cout<<" g(x)= "; cout<<g;
s=f+g;
cout<<"f(x)+g(x) = "; cout<<s;
s=f*g;
cout<<" f(x)*g(x) = "; cout<<s;
s=masp[0]; cout<<masp[0];
for(i=1;i<m;i++)
{ s=s+masp[i]; cout<<masp[i];}
cout<<"Summa: "; cout<< s;
while(!kbhit());
delete p1;
return 0;
}
Задания для самостоятельного решения
Разработать перечисленные ниже классы. При разработке каждого класса возможны два варианта решения: а) данные-члены класса представляют собой переменные и массивы фиксированной размерности; б) память для данных-членов класса выделяется динамически.
1. «Комплексное число» – Complex. Класс должен содержать несколько конструкторов и операции для сложения, вычитания, умножения, деления, присваивания. Создать два вектора размерности из комплексных координат. Передать их в функцию, которая выполняет сложение комплексных векторов.
2. Определить класс «Дробь» – Fraction в виде пары . Класс должен содержать несколько конструкторов. Реализовать методы для сложения, вычитания, умножения и деления дробей. Перегрузить операции сложения, вычитания, умножения, деления, присваивания и операции отношения. Создать массив объектов и передать его в функцию, которая изменяет каждый элемент массива с четным индексом путем добавления следующего за ним элемента массива.
3. Разработать класс «Вектор» – Vector размерности . Определить несколько конструкторов, в том числе конструктор копирования. Реализовать методы для вычисления модуля вектора, скалярного произведения, сложения, вычитания, умножения на константу. Перегрузить операции сложения, вычитания, умножения, инкремента, декремента, индексирования, присваивания для данного класса. Создать массив объектов. Написать функцию, которая для заданной пары векторов будет определять, являются ли они коллинеарными или ортогональными.
4. Определить класс «Квадратная матрица» – Matrix. Класс должен содержать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для сложения, вычитания, умножения матриц; вычисления нормы матрицы. Перегрузить операции сложения, вычитания, умножения и присваивания для данного класса. Создать массив объектов класса Matrix и передать его в функцию, которая изменяет -ю матрицу путем возведения ее в квадрат. В головной программе вывести результат.
5. Разработать класс «Многочлен» – Polynom степени . Написать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для вычисления значения полинома; сложения, вычитания и умножения полиномов. Перегрузить операции сложения, вычитания, умножения, инкремента, декремента, индексирования, присваивания. Создать массив объектов класса. Передать его в функцию, вычисляющую сумму полиномов массива и возвращающую полином-результат, который выводится на экран в головной программе.
6. Определить класс «Стек» – Stack. Элементы стека хранятся в массиве. Если массив имеет фиксированную размерность, то предусмотреть контроль выхода за пределы массива. Если память выделяется динамически и ее не хватает, то увеличить размер выделенной памяти. Включение элементов в стек и их извлечение реализовать как в виде методов, так и с помощью перегруженных операций. Создать массив объектов класса Stack. Передавать объекты в функцию, которая удаляет из стека первый (сверху), третий, пятый и т. д. элементы.
7. Построить классы для описания плоских фигур: круг, квадрат, прямоугольник. Включить методы для изменения объектов, перемещения на плоскости, вращения. Перегрузить операции, реализующие те же действия. Выполнить тестирование класса, создав массив объектов.
8. Определить класс «Строка» – String длины n. Написать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для выполнения конкатенации строк, извлечения символа из заданной позиции, сравнения строк. Перегрузить операции сложения, индексирования, отношения, добавления , присваивания для данного класса. Создать массив объектов и передать его в функцию, которая выполняет сортировку строк.
9. Разработать класс «Множество (целых чисел, символов, строк и т. д.)» – Set мощности n. Написать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для определения принадлежности заданного элемента множеству, пересечения, объединения, разности двух множеств. Перегрузить операции сложения, вычитания, умножения (пересечения), индексирования, присваивания. Создать массив объектов и передавать пары объектов в функцию, которая строит множество, состоящее из элементов, входящих только в одно из заданных множеств, т. е. , и возвращает его в головную программу.
10. Разработать класс для массива строк. Написать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для поэлементной конкатенации двух массивов, упорядочения строк в лексикографическом порядке, слияния двух массивов с удалением повторяющихся строк, а также для вывода на экран всего массива и заданной строки. Перегрузить операции сложения, умножения, индексирования, присваивания для данного класса. Создать массив объектов и передавать объекты в функцию, которая выполняет слияние объектов и для полученного объекта-результата производит лексикографическое упорядочения строк.
11. Составить описания класса, обеспечивающего представление матрицы заданного размера n´m и любого минора в ней. Память для матрицы выделять динамически. Написать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для отображения на экране как матрицы в целом, так и заданного минора, а также для изменения минора; сложения, вычитания, умножения миноров. Перегрузить операции сложения, вычитания, умножения и присваивания для данного класса. Создать массив объектов данного класса и передать его в функцию, которая изменяет для -й матрицы ее минор путем умножения на константу.
12. Построить класс «Булев вектор» – BoolVector размерности . Определить несколько конструкторов, в том числе конструктор копирования. Реализовать методы для выполнения поразрядных конъюнкции, дизъюнкции и отрицания векторов, а также подсчета числа единиц и нулей в векторе. Реализовать те же действия над векторами с помощью перегруженных операций. Перегрузить операции отношения и присваивания для данного класса. Создать массив объектов. Передавать объекты в функцию, которая будет их изменять по формуле .
13. Реализовать класс «Троичный вектор» – Tvector размерности n. Компоненты вектора принимают значения из множества . Два троичных вектора tk =(t 1 k,…,t nk) и tl =(t 1 l,…, tnl) называются ортогональными, если существует такое i, что tik, til Î{0,1} и tik ¹ til. Операция пересечения не ортогональных векторов выполняется покомпонентно по следующим правилам: 1Ç1=1Ç X = X Ç1=1, 0Ç0=0Ç X = X Ç0=0, X Ç X = X. Реализовать методы для проверки векторов на ортогональность, для пересечения не ортогональных векторов, сравнения векторов, подсчета числа компонент, равных X. Осуществить те же действия над векторами с помощью перегруженных операций. Перегрузить операцию присваивания для данного класса. Выполнить тестирование класса, создав массив объектов.
14. Определить класс «Булева матрица» – BoolMatrix размерности n´m. Класс должен содержать несколько конструкторов, в том числе конструктор копирования. Реализовать методы для логического сложения (дизъюнкции), умножения и инверсии матриц. Реализовать методы для подсчета числа единиц в матрице и лексикографического упорядочения строк. Перегрузить операции для логического сложения, умножения и инверсии матриц, а также операцию присваивания. Создать массив объектов класса BoolMatrix. Передавать объекты в функцию, которая их изменяет по формуле .
Тесты
1. В какой строке допущена ошибка?
class X {
int a;
int f() const; //1
int g() {return a++;} //2
int h() const {return a++;} //3
};
Варианты ответа:
1) здесь нет ошибок; (*) 2) //3; 3) //2; 4) //1.
2. Выберите три верных утверждения:
[1] статическая функция-член класса, не обладает указателем this;
[2] статическая функция-член класса, может быть виртуальной;
[3] в классе не может быть двух функций: статической и нестатической – с одним и тем же именем и списком параметров;
[4] статическая функция в классе не может быть объявлена const.
Варианты ответа:
1) все утверждения не верны; (*) 2) [4]; (*) 3) [3]; 4) [2]; (*) 5) [1].
3 Правильно ли перегружены функции?
class X {
static void f();
void f() const;
};
Варианты ответа:
*1) нет; 2) да; 3) да, если убрать const.
4. Какие из операторов не могут быть перегружены?
Варианты ответа:
1) new; *2).; 3) *; 4) []; 5) ().
5. Что будет выведено?
#include < iostream.h >
class X {
int a;
public:
X(): a(1) {}
X& operator++() {a++; return *this;};
X& operator++(int) {a--; return *this;};
friend ostream& operator<<(ostream&, X&);
};
ostream& operator<<(ostream& _stream, X& _x) {
_stream << _x.a;
return _stream;
}
void main() {
X x;
cout << ++x;
cout << x++;
}
Варианты ответа:
1) ничего; *2) 21; 3) 12; 4) 22; 5) 11.
6. Даны следующие три свойства, которыми обладает функция-член класса:
[1] функция имеет право доступа к закрытой части объявления класса;
[2] функция находится в области видимости класса;
[3] функция должна вызываться для объекта класса (имеется указатель this).
Какими из этих свойств обладает дружественная функция?
Варианты ответа:
1) [3]; 2) ни одним; 3) [2]; *4) [1].
7. Какие функции являются неявно inline? Выберите три варианта ответа.
[1] все дружественные функции;
[2] дружественные функции, определенные в классе;
[3] неявный конструктор по умолчанию;
[4] неявный деструктор по умолчанию;
[5] виртуальные функции.
Варианты ответа:
1) [5]; *2) [4]; *3) [3]; *4) [2]; 5) [1].
8. Дан следующий код:
class X {
friend void f(X&);
};
С помощью какого синтаксиса может быть вызвана функция f?
Варианты ответа:
1) f не может быть вызвана, т. к. она объявлена как private; 2) X x; X::f(x); 3) X x; f(&x); 4) X x; x.f(x); *5) X x; f(x).