1. Виртуелен деструктор и задачи за вежбање
1.1. Виртуелен деструктор
1.1.1. Пример 1 – Зошто и кога е потребен виртуелен деструктор?
oop_av121a.cpp
#include <iostream>
using namespace std;
class Osnovna {
public:
Osnovna() { cout << "Konstruiram objekt od Osnovna\n";}
// ова е деструктор:
~Osnovna() { cout << "Unishtuvam objekt od Osnovna\n";}
};
class Izvedena : public Osnovna
{
public:
Izvedena() { cout << "Konstruiram objekt od Izvedena\n"; }
~Izvedena() { cout << "Unishtuvam objekt od Izvedena\n"; }
};
int main() {
Osnovna *osnovnaPok = new Izvedena();
delete osnovnaPok;
}
Konstruiram objekt od Osnovna Konstruiram objekt od Izvedena Unishtuvam objekt od Osnovna
oop_av121b.cpp
#include <iostream>
using namespace std;
class Osnovna {
public:
Osnovna() { cout << "Konstruiram objekt od Osnovna\n";}
// ова е деструктор:
virtual ~Osnovna() { cout << "Unishtuvam objekt od Osnovna\n";}
};
class Izvedena : public Osnovna
{
public:
Izvedena() { cout << "Konstruiram objekt od Izvedena\n"; }
~Izvedena() { cout << "Unishtuvam objekt od Izvedena\n"; }
};
int main() {
Osnovna *osnovnaPok = new Izvedena();
delete osnovnaPok;
}
Konstruiram objekt od Osnovna Konstruiram objekt od Izvedena Unishtuvam objekt od Izvedena Unishtuvam objekt od Osnovna
1.2. Втор колоквиум 2015/2016
1.2.1. Задача 1
Издавачката куќа FINKI-Education издава онлајн и печатени книги. За секоја книга се чуваат податоци за ISBN бројот (низа од најмногу 20 знаци), насловот (низа од најмногу 50 знаци), авторот (низа од најмногу 30 знаци) и основната цена изразена во $ (реален број). Класата за опишување на книгите е апстрактна (5 поени).
За секоја онлајн книга дополнително се чуваат податоци за url од каде може да се симне (динамички резервирана низа од знаци) и големината изразена во MB (цел број). За секоја печатена книга дополнително се чуваат податоци за масата изразена во килограми (реален број) и дали ја има на залиха (логичка променлива). (5 поени)
За секој објект од двете изведени класи треба да бидат на располагање следниве методи:
-
Метод
bookPrice
, за пресметување на продажната цена на книгата на следниот начин: (10 поени)-
За онлајн книга - цената се зголемува за 20% од основната цена ако книгата е поголема од 20MB
-
За печатена книга - цената се зголемува за 15% од основната цена ако масата на книгата е поголема од 0.7kg
-
-
Преоптоварен оператор
>
за споредба на две книги од каков било вид според нивната цена. (5 поени) -
Преоптоварен оператор
<<
за печатење на податоците за книгите во формат: (5 поени)[ISBN]: [Наслов], [Автор] [Продажна цена]
Да се имплементира функција mostExpensiveBook со потпис: void mostExpensiveBook (Book** books, int n)
во која се печати вкупниот број на онлајн, односно, печатени книги во проследената низа посебно. (5 поени) Потоа се наоѓа и печати најскапата книга. (5 поени)
Да се обезбедат сите потребни функции за правилно функционирање на програмата. (5 поени)
oop_av122.cpp
#include<iostream>
#include<string.h>
using namespace std;
class Book {
protected:
char isbn[20];
char title[50];
char author[30];
float price;
public:
Book(const char* isbn = "", const char* title = "", const char* author = "", float price = 0) {
strncpy(this->isbn, isbn, 19);
this->isbn[19] = 0;
strncpy(this->title, title, 49);
this->title[49] = 0;
strncpy(this->author, author, 29);
this->author[29] = 0;
this->price = price;
}
void setISBN(char *isbn) {
strncpy(this->isbn, isbn, 19);
this->isbn[19] = 0;
}
virtual float bookPrice() = 0;
char* getISBN() { return isbn; }
friend ostream& operator<< (ostream& o, Book& b) {
o << b.isbn << ": " << b.title << ", " << b.author << " " << b.bookPrice() << endl;
return o;
}
virtual ~Book() {}
};
float Book::bookPrice() {
return price;
}
bool operator>(Book& b1, Book& b2) {
return (b1.bookPrice() > b2.bookPrice());
}
class OnlineBook : public Book {
private:
char* url;
int size;
public:
OnlineBook(const char* isbn = "", const char* title = "", const char* author = "", float price = 0, const char* url = "", int size = 0): Book(isbn, title, author, price) {
this->url = new char[strlen(url) + 1];
strcpy(this->url, url);
this->size = size;
}
OnlineBook(OnlineBook& ob) {
strcpy(isbn, ob.isbn);
strcpy(title, ob.title);
strcpy(author, ob.author);
price = ob.price;
url = new char[strlen(ob.url) + 1];
strcpy(url, ob.url);
size = ob.size;
}
OnlineBook& operator=(OnlineBook& ob) {
if (this != &ob) {
strcpy(isbn, ob.isbn);
strcpy(title, ob.title);
strcpy(author, ob.author);
price = ob.price;
delete[] url;
url = new char[strlen(ob.url) + 1];
strcpy(url, ob.url);
size = ob.size;
}
return *this;
}
~OnlineBook() {
delete[] url;
}
float bookPrice() {
if (size > 20)
return Book::bookPrice() * 1.2;
return Book::bookPrice();
}
};
class PrintBook : public Book {
private:
float weight;
bool inStock;
public:
PrintBook(const char* isbn = "", const char* title = "", const char* author = "", float price = 0, float weight = 0, bool inStock = false): Book(isbn, title, author, price) {
this->weight = weight;
this->inStock = inStock;
}
float bookPrice() {
if (weight > 0.7)
return Book::bookPrice() * 1.15;
return Book::bookPrice();
}
};
void mostExpensiveBook(Book** books, int n) {
int obNo = 0;
int pbNo = 0;
for (int i = 0; i < n; i++)
{
OnlineBook* ob = dynamic_cast<OnlineBook*>(books[i]);
if (ob != 0)
obNo++;
PrintBook* pb = dynamic_cast<PrintBook*>(books[i]);
if (pb != 0)
pbNo++;
}
cout << "FINKI-Education" << endl;
cout << "Total number of online books: " << obNo << endl;
cout << "Total number of print books: " << pbNo << endl;
Book* max = books[0];
for (int i = 1; i < n; i++)
if (*books[i] > *max)
max = books[i];
cout << "The most expensive book is: " << endl;
cout << *max;
}
1.3. Задача 2
Да се имплементира класа Trud
во која се чуваат информации за: (5 поени)
-
вид на труд (еден знак и тоа C за конференциски труд, J за труд во списание)
-
година на издавање (цел број).
Да се имплементира класа Student
во која се чува: (5 поени)
-
името на студентот (низа од најмногу 30 карактери)
-
индекс (цел број)
-
година на упис (цел број)
-
листа на оцени од положени предмети (низа од цели броеви)
-
број на положени предмети (цел број).
За оваа класа да се имплементираат следните методи:
-
функција rang() што пресметува просек од положените испити на студентот (5 поени)
-
оператор << за печатење на студентот во формат: (5 поени)
Индекс Име Година на упис ранг
Да се имплементира класа PhDStudent
во која покрај основните информации за студентот дополнително се чува: (5 поени):
-
листа од објавени трудови (динамички резервирана низа од објекти од класата
Trud
) -
бројот на трудови (цел број).
Во оваа класа да се препокрие соодветно функцијата rang()
така што на просекот од положените испити ќе се додаде и збирот од поените од објавените трудови на PhD студентот.
Во зависност од видот на трудот, секој универзитет има посебен начин на бодување на трудовите.
Начинот на бодување е ист за сите PhD студенти.
Иницијално да се смета дека конференциски труд се бодува со 1 поен, а труд во списание со 3 поени.
Универзитетот има можност да ги менува вредностите на бодовите. (5 поени + 5 поени)
За оваа класа да се обезбеди:
-
оператор
+=
за додавање нов објект од класата Trud во листата (5 поени). Ако се направи обид да се внесе труд што е издаден порано од годината на упис на студентот да се фрли исклучок (објект од класатаException
). Справувањето со исклучокот треба да се реализира во главната функција main каде што е потребно, но и во конструктор ако е потребно. Ако бил генериран исклучок треба да се отпечати соодветна порака за грешка "Ne moze da se vnese dadeniot trud", а новиот труд нема да се внесе во листата на трудови од студентот. (10 поени)
Сите променливи на класите се чуваат како приватни. |
Да се обезбедат сите потребни функции за правилно функционирање на програмата. (5 поени)
oop_av123.cpp
#include<iostream>
#include<string.h>
using namespace std;
class Exception {
public:
void print() {
cout << "Ne moze da se vnese dadeniot trud" << endl;
}
};
class Trud {
private:
char tip;
int god;
public:
Trud(const char tip = 'C', int god = 0) {
this->tip = toupper(tip);
this->god = god;
}
int getGod() {
return god;
}
char getTip() {
return tip;
}
friend istream& operator>>(istream& in, Trud &t) {
in >> t.tip >> t.god;
return in;
}
};
class Student {
private:
char ime[30];
int indeks;
int god;
int oceni[50];
int n;
public:
Student() {}
Student(const char* ime, int indeks, int god, int *oceni, int n) {
strcpy(this->ime, ime);
this->indeks = indeks;
this->god = god;
this->n = n;
for (int i = 0; i < n; i++)
this->oceni[i] = oceni[i];
}
int getGod() {
return god;
}
int getIndeks() {
return indeks;
}
virtual float rang() {
int suma = 0;
for (int i = 0; i < n; i++)
suma += oceni[i];
return (float)suma / n;
}
friend ostream& operator<< (ostream& o, Student& st)
{
o << st.indeks << " " << st.ime << " " << st.god << " " << st.rang() << endl;
return o;
}
virtual ~Student() {}
};
class PhDStudent : public Student {
private:
Trud *t;
int nt;
static int conf;
static int journal;
public:
PhDStudent(const char* ime, int indeks, int god, int *oceni, int n, Trud* t, int nt) : Student(ime, indeks, god, oceni, n) {
//this->nt = nt;
this->t = new Trud[100];
int ok = 0;
for (int i = 0; i < nt; i++) {
try {
if (this->getGod() > t[i].getGod()) throw Exception();
this->t[ok] = t[i];
ok++;
}
catch (Exception e) {
e.print();
//this->nt--;
}
}
this->nt = ok
}
float rang() {
int suma = 0;
for (int i = 0; i < nt; i++) {
if (t[i].getTip() == 'C')
suma += conf;
else
suma += journal;
}
return Student::rang() + suma;
}
static void setConf(int c) {
PhDStudent::conf = c;
}
static void setJournal(int j) {
PhDStudent::journal = j;
}
void operator+=(Trud &tr) {
if (this->getGod() > tr.getGod()) throw Exception();
this->t[nt] = tr;
this->nt++;
}
~PhDStudent() {
delete[] t;
}
};
int PhDStudent::conf = 1;
int PhDStudent::journal = 3;