Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Лабораторная работа №7. Наследование.

1. Представьте себе издательскую компанию, которая торгует книгами и аудиозаписями этих книг. Создайте класс publication, в котором хранятся название (строка) и цена (типа float) книги. От этого класса наследуются еще два класса: book, который содержит информацию о количестве страниц в книге (типа int), и type, который содержит время записи книги в минутах (тип float). В каждом из этих трех классов должен быть метод getdata(), через который можно получать данные от пользователя с клавиатуры, и putdata(), предназначенный для вывода этих данных.

Напишите функцию main() программы для проверки классов book и type. Создайте их объекты в программе и запросите пользователя ввести и вывести данные с использованием методов getdataQ и putdata().

// lab8_1.cpp

// publication class and derived classes

#include <iostream>

#include <string>

using namespace std;

////////////////////////////////////////////////////////////////

class publication // base class

{

private:

string title;

float price;

public:

void getdata()

{

cout << "\nEnter title: "; cin >> title;

cout << "Enter price: "; cin >> price;

}

void putdata() const

{

cout << "\nTitle: " << title;

cout << "\nPrice: " << price;

}

};

////////////////////////////////////////////////////////////////

class book: private publication // derived class

{

private:

int pages;

public:

void getdata()

{

publication::getdata();

cout << "Enter number of pages: "; cin >> pages;

}

void putdata() const

{

publication::putdata();

cout << "\nPages: " << pages;

}

};

////////////////////////////////////////////////////////////////

class tape: private publication // derived class

{

private:

float time;

public:

void getdata()

{

publication::getdata();

cout << "Enter playing time: "; cin >> time;

}

void putdata() const

{

publication::putdata();

cout << "\nPlaying time: " << time;

}

};

////////////////////////////////////////////////////////////////

int main()

{

book book1; // define publications

tape tape1;

 

book1.getdata(); // get data for them

tape1.getdata();

 

book1.putdata(); // display their data

tape1.putdata();

cout << endl;

return 0;

}

 

2. Пусть SZ – константа, которая обозначает количество символов в строке. Создайте класс Pstring, производный от класса String, в котором предотвратите возможность переполнения буфера при определении слишком длинной строковой константы. Класс String, соответственно, должен иметь в поле, котором хранится строка, ограничение на количество символов в строке (буфер ограниченной длины). Новый конструктор производного класса будет копировать в str только SZ-1 символов, если строка окажется слишком длинной, и будет копировать строку полностью, если она будет иметь длину меньшую, чем SZ. Напишите функцию main() программы для проверки ее работы со строками разной длины.

// lab8_2.cpp

//inheritance from String class

#include <iostream>

#include <cstring> //for strcpy(), etc.

using namespace std;

////////////////////////////////////////////////////////////////

class String //base class

{

protected: //Note: can't be private

enum { SZ = 80 }; //size of all String objects

char str[SZ]; //holds a C-string

public:

String() //constructor 0, no args

{ str[0] = '\0'; }

String(char s[]) //constructor 1, one arg

{ strcpy(str, s); } // convert string to String

void display() const //display the String

{ cout << str; }

operator char*() //conversion function

{ return str; } //convert String to C-string

};

////////////////////////////////////////////////////////////////

class Pstring: public String //derived class

{

public:

Pstring(char s[]); //constructor

};

//--------------------------------------------------------------

Pstring::Pstring(char s[]) //constructor for Pstring

{

if(strlen(s) > SZ-1) //if too long,

{

for(int j=0; j<SZ-1; j++) //copy the first SZ-1

str[j] = s[j]; //characters "by hand"

str[j] = '\0'; //add the null character

}

else //not too long,

String(s); //so construct normally

}

////////////////////////////////////////////////////////////////

int main()

{ //define String

Pstring s1 = "This is a very long string which is probably "

"no, certainly--going to exceed the limit set by SZ.";

cout << "\ns1="; s1.display(); //display String

 

Pstring s2 = "This is a short string."; //define String

cout << "\ns2="; s2.display(); //display String

cout << endl;

return 0;

}

 

3. Начните с классов book, type и publication из упражнения 1. Добавьте базовый класс sales, в котором содержится массив, состоящий из трех значений типа float, куда можно записать общую стоимость проданных книг за последние три месяца. Включите в класс методы getdata() для получения значений стоимости от пользователя и putdata() для вывода этих цифр. Измените классы book и type так, чтобы они стали производными обоих классов: publications и sales. Объекты классов book и type должны вводить и выводить данные о продажах вместе с другими своими данными. Напишите функцию main() для создания объектов классов book и type, чтобы протестировать возможности ввода/вывода данных.

// lab8_3.cpp

// multiple inheritance with publication class

#include <iostream>

#include <string>

using namespace std;

////////////////////////////////////////////////////////////////

class publication

{

private:

string title;

float price;

public:

void getdata()

{

cout << "\nEnter title: "; cin >> title;

cout << " Enter price: "; cin >> price;

}

void putdata() const

{

cout << "\nTitle: " << title;

cout << "\n Price: " << price;

}

};

////////////////////////////////////////////////////////////////

class sales

{

private:

enum { MONTHS = 3 };

float salesArr[MONTHS];

public:

void getdata();

void putdata() const;

};

//--------------------------------------------------------------

void sales::getdata()

{

cout << " Enter sales for 3 months\n";

for(int j=0; j<MONTHS; j++)

{

cout << " Month " << j+1 << ": ";

cin >> salesArr[j];

}

}

//--------------------------------------------------------------

void sales::putdata() const

{

for(int j=0; j<MONTHS; j++)

{

cout << "\n Sales for month " << j+1 << ": ";

cout << salesArr[j];

}

}

////////////////////////////////////////////////////////////////

class book: private publication, private sales

{

private:

int pages;

public:

void getdata()

{

publication::getdata();

cout << " Enter number of pages: "; cin >> pages;

sales::getdata();

}

void putdata() const

{

publication::putdata();

cout << "\n Pages: " << pages;

sales::putdata();

}

};

////////////////////////////////////////////////////////////////

class tape: private publication, private sales

{

private:

float time;

public:

void getdata()

{

publication::getdata();

cout << " Enter playing time: "; cin >> time;

sales::getdata();

}

void putdata() const

{

publication::putdata();

cout << "\n Playing time: " << time;

sales::putdata();

}

};

////////////////////////////////////////////////////////////////

int main()

{

book book1; // define publications

tape tape1;

 

book1.getdata(); // get data for publications

tape1.getdata();

 

book1.putdata(); // display data for publications

tape1.putdata();

cout << endl;

return 0;

}

 

4. Предположим, что издатель из упражнений 1 и 3 решил добавить к своей продукции версии книг на компьютерных дисках для тех, кто любит читать книги на своих компьютерах. Добавьте класс disk, который, как book и type, является производным класса publication. Класс disk должен включать в себя те же функции, что и в других классах. Полем только этого класса будет тип диска: CD или DVD. Для хранения этих данных вы можете ввести тип enum. Пользователь должен выбрать подходящий тип, набрав на клавиатуре с или d.

 

5. Создайте производный класс employee2 от базового класса employee (приведён ниже). Добавьте в новый класс поле compensation типа double и поле period типа enum для обозначения периода оплаты работы служащего: почасовая, понедельная или помесячная.

const int LEN = 80; //maximum length of names

////////////////////////////////////////////////////////////////

class employee //employee class

{

private:

char name[LEN]; //employee name

unsigned long number; //employee number

public:

void getdata()

{

cout << "\n Enter last name: "; cin >> name;

cout << " Enter number: "; cin >> number;

}

void putdata() const

{

cout << "\n Name: " << name;

cout << "\n Number: " << number;

}

};

 

6. Используя наследование, добавьте к классу, который приведён ниже, возможность для пользователя определять верхнюю и нижнюю границы массива в конструкторе.

const int LIMIT = 100; //array size

////////////////////////////////////////////////////////////////

class safearay

{

private:

int arr[LIMIT];

public:

int& operator [](int n) //note: return by reference

{

if(n< 0 || n>=LIMIT)

{ cout << "\nIndex out of bounds"; exit(1); }

return arr[n];

}

};

 

7. Используя наследование на приведённом ниже классе, добавьте возможность использования постфиксных операций для случаев увеличения и уменьшения.

// constructors in derived class

#include <iostream>

using namespace std;

////////////////////////////////////////////////////////////////

class Counter

{

protected: //NOTE: not private

unsigned int count; //count

public:

Counter(): count(0) //constructor, no args

{ }

Counter(int c): count(c) //constructor, one arg

{ }

unsigned int get_count() const //return count

{ return count; }

Counter operator ++ () //incr count (prefix)

{ return Counter(++count); }

};

////////////////////////////////////////////////////////////////

class CountDn: public Counter

{

public:

CountDn(): Counter() //constructor, no args

{ }

CountDn(int c): Counter(c) //constructor, 1 arg

{ }

CountDn operator -- () //decr count (prefix)

{ return CountDn(--count); }

};

////////////////////////////////////////////////////////////////

int main()

{

CountDn c1; //class CountDn

CountDn c2(100);

 

cout << "\nc1=" << c1.get_count(); //display

cout << "\nc2=" << c2.get_count(); //display

 

++c1; ++c1; ++c1; //increment c1

cout << "\nc1=" << c1.get_count(); //display it

 

--c2; --c2; //decrement c2

cout << "\nc2=" << c2.get_count(); //display it

 

CountDn c3 = --c2; //create c3 from c2

cout << "\nc3=" << c3.get_count(); //display c3

cout << endl;

return 0;

}

8. В некоторых компьютерных языках, таких, как Visual Basic, есть операции, с помощью которых можно выделить часть строки и присвоить ее другой строке. (В стандартном классе string предложены различные под ходы). Используя наследование, добавьте такую возможность в класс Pstring из упражнения 2. В новом производном классе Pstring2 разместите три новых функции: left(), mid() и right(), которые будут принимать:

 

Left() – один аргумент, количество символов, которое будет вырезано с левого края

Right() – один аргумент, количество символов, которое будет вырезано с правого края

Mid() – два аргумента. Первый – количество символов, которое будет вырезано, второй – с какого символа начинать резать.

 

9. Вспомним классы publication, book и type из упражнения 1. Предположим, что мы хотим добавить в классы book и type дату выхода книги. Создайте новый производный класс publication2, который является производным класса publication и включает в себя поле, хранящее эту дату. Затем измените классы book и type так, чтобы они стали производными класса publication2 вместо publication. Сделайте необходимые изменения функций классов так, чтобы пользователь мог вводить и выводить дату выхода книги.

 

10. Создайте производный от класса manager класс executive. (Мы предполагаем, что управляющий — это главный менеджер.) Добавочными данными этого класса будут размер годовой премии и количество его акций в компании. Добавьте подходящие методы для этих данных, позволяющие их вводить и выводить.

//multiple inheritance with employees and degrees

#include <iostream>

using namespace std;

const int LEN = 80; //maximum length of names

////////////////////////////////////////////////////////////////

class student //educational background

{

private:

char school[LEN]; //name of school or university

char degree[LEN]; //highest degree earned

public:

void getedu()

{

cout << " Enter name of school or university: ";

cin >> school;

cout << " Enter highest degree earned \n";

cout << " (Highschool, Bachelor's, Master's, PhD): ";

cin >> degree;

}

void putedu() const

{

cout << "\n School or university: " << school;

cout << "\n Highest degree earned: " << degree;

}

};

////////////////////////////////////////////////////////////////

class employee

{

private:

char name[LEN]; //employee name

unsigned long number; //employee number

public:

void getdata()

{

cout << "\n Enter last name: "; cin >> name;

cout << " Enter number: "; cin >> number;

}

void putdata() const

{

cout << "\n Name: " << name;

cout << "\n Number: " << number;

}

};

////////////////////////////////////////////////////////////////

class manager: private employee, private student //management

{

private:

char title[LEN]; //"vice-president" etc.

double dues; //golf club dues

public:

void getdata()

{

employee::getdata();

cout << " Enter title: "; cin >> title;

cout << " Enter golf club dues: "; cin >> dues;

student::getedu();

}

void putdata() const

{

employee::putdata();

cout << "\n Title: " << title;

cout << "\n Golf club dues: " << dues;

student::putedu();

}

};

////////////////////////////////////////////////////////////////

class scientist: private employee, private student //scientist

{

private:

int pubs; //number of publications

public:

void getdata()

{

employee::getdata();

cout << " Enter number of pubs: "; cin >> pubs;

student::getedu();

}

void putdata() const

{

employee::putdata();

cout << "\n Number of publications: " << pubs;

student::putedu();

}

};

////////////////////////////////////////////////////////////////

class laborer: public employee //laborer

{

};

////////////////////////////////////////////////////////////////

int main()

{

manager m1;

scientist s1, s2;

laborer l1;

 

cout << endl;

cout << "\nEnter data for manager 1"; //get data for

m1.getdata(); //several employees

 

cout << "\nEnter data for scientist 1";

s1.getdata();

 

cout << "\nEnter data for scientist 2";

s2.getdata();

 

cout << "\nEnter data for laborer 1";

l1.getdata();

 

cout << "\nData on manager 1"; //display data for

m1.putdata(); //several employees

 

cout << "\nData on scientist 1";

s1.putdata();

 

cout << "\nData on scientist 2";

s2.putdata();

 

cout << "\nData on laborer 1";

l1.putdata();

cout << endl;

return 0;

}

 

 

11. В различных ситуациях иногда требуется работать с двумя числами, объединенными в блок. Например, каждая из координат экрана имеет горизонтальную составляющую (х) и вертикальную (у). Представьте такой блок чисел в качестве структуры pair, которая содержит две переменные типа int. Теперь предположим, что мы хотим иметь возможность хранить переменные типа pair в стеке. То есть мы хотим иметь возможность положить переменную тина pair в стек путем вызова метода push() с переменной типа pair в качестве аргумента и вынуть ее из стека путем вызова метода рор(), возвращающего переменную типа pair. Начнем с класса Stack2, что првиедён ниже. Создадим производный от него класс pairStack. В нем будут содержаться два метода: перегружаемый метод push() и перегружаемый метод рор(). Метод pairStack::push() должен будет сделать два вызова метода Stack2::push(), чтобы сохранить оба числа из пары, а метод pairStack::pop() должен будет сделать два вызова метода Stack2::pop().

 

12. Рассмотрим старую Британскую платежную систему фунты-стерлинги-пенсы. Пенни в дальнейшем делятся на фартинги и полупенни. Фартинг — это 1/4 пенни. Существовали монеты фартинг, полфартиига и пенни. Любые сочетания монет выражались через восьмые части пенни:

1/8 пенни — это полфартинга;

1/4 пенни — это фартинг;

3/8 пенни — это фартинг с половиной;

1/2 пенни — это полпенни;

5/8 пенни — это полфартинга плюс полпенни;

3/4 пенни — это полпенни плюс фартинг;

7/8 пенни — эго полпенни плюс фартинг с половиной.

Давайте предположим, что мы хотим добавить в класс sterling возможность пользоваться этими дробными частями пенни. Формат ввода/вывода может быть похожим на £1.1.1-1/4 или £9.19.11-7/8, где дефисы отделяют дробные части от пенни.

Создайте новый класс sterfrac, производный от класса sterling. В нем должна быть возможность выполнения четырех основных арифметических операций со стерлинх'ами, включая восьмые части пенни. Поле eighths типа int определяет количество восьмых. Вам нужно будет перегрузить методы класса sterling, чтобы они могли работать с восьмыми частями. Пользователь должен иметь возможность ввести и вывести дробные части пенни.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...