Task 1: Publisher Class Hierarchy
The following code demonstrates inheritance and polymorphism using a publisher class hierarchy:
main.cpp
#include "publisher.hpp"
#include <vector>
#include <typeinfo>
using std::vector;
void demonstrate_polymorphism() {
vector<Publisher*> media_collection;
media_collection.push_back(new Book("Harry Potter", "J.K. Rowling"));
media_collection.push_back(new Film("The Godfather", "Francis Ford Coppola"));
media_collection.push_back(new Music("Blowing in the wind", "Bob Dylan"));
for(auto &media_ptr: media_collection) {
cout << "Pointer type: " << typeid(media_ptr).name() << endl;
cout << "RTTI type: " << typeid(*media_ptr).name() << endl;
media_ptr->publish();
media_ptr->use();
cout << endl;
}
}
int main() {
demonstrate_polymorphism();
}
publisher.hpp
#pragma once
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
// Abstract base class for media publications
class Publisher {
public:
Publisher(const string &s = "");
public:
virtual void publish() const = 0;
virtual void use() const = 0;
protected:
string title;
};
Publisher::Publisher(const string &s): title {s} {
}
// Book class derived from Publisher
class Book: public Publisher {
public:
Book(const string &s = "", const string &a = "");
public:
void publish() const override;
void use() const override;
private:
string author;
};
Book::Book(const string &s, const string &a): Publisher{s}, author{a} {
}
void Book::publish() const {
cout << "Publishing book: 《" << title << "》 by " << author << endl;
}
void Book::use() const {
cout << "Reading book: " << title << " by " << author << endl;
}
// Film class derived from Publisher
class Film: public Publisher {
public:
Film(const string &s = "", const string &d = "");
public:
void publish() const override;
void use() const override;
private:
string director;
};
Film::Film(const string &s, const string &d): Publisher{s}, director{d} {
}
void Film::publish() const {
cout << "Publishing film: <" << title << "> directed by " << director << endl;
}
void Film::use() const {
cout << "Watching film: " << title << " directed by " << director << endl;
}
// Music class derived from Publisher
class Music: public Publisher {
public:
Music(const string &s = "", const string &a = "");
public:
void publish() const override;
void use() const override;
private:
string artist;
};
Music::Music(const string &s, const string &a): Publisher{s}, artist{a} {
}
void Music::publish() const {
cout << "Publishing music <" << title << "> by " << artist << endl;
}
void Music::use() const {
cout << "Listening to music: " << title << " by " << artist << endl;
}
Task 2: Book Sales System
This task implements a book sales tracking system with sorting capabilities:
main.cpp
#include "booksale.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
// Comparison function for sorting by sales quantity
bool sort_by_quantity(const BookSale &item1, const BookSale &item2) {
return item1.get_quantity() > item2.get_quantity();
}
void process_sales() {
using namespace std;
vector<BookSale> sales_records;
int book_count;
cout << "Enter number of books: ";
cin >> book_count;
cout << "Enter book sales records" << endl;
for(int i = 0; i < book_count; ++i) {
string title, author, translator, isbn;
float price;
cout << string(20, '-') << "Book " << i+1 << " Information" << string(20, '-') << endl;
cout << "Enter title: "; cin >> title;
cout << "Enter author: "; cin >> author;
cout << "Enter translator: "; cin >> translator;
cout << "Enter ISBN: "; cin >> isbn;
cout << "Enter price: "; cin >> price;
Book book(title, author, translator, isbn, price);
float sale_price;
int quantity_sold;
cout << "Enter sale price: "; cin >> sale_price;
cout << "Enter quantity sold: "; cin >> quantity_sold;
BookSale record(book, sale_price, quantity_sold);
sales_records.push_back(record);
}
// Sort by quantity sold
sort(sales_records.begin(), sales_records.end(), sort_by_quantity);
// Display sorted sales information
cout << string(20, '=') << "Book Sales Statistics" << string(20, '=') << endl;
for(auto &sale: sales_records) {
cout << sale << endl;
cout << string(40, '-') << endl;
}
}
int main() {
process_sales();
}
booksale.hpp
#pragma once
#include "book.hpp"
#include <iostream>
#include <string>
#include <iomanip>
using std::string;
using std::cout;
using std::endl;
using std::setw;
class BookSale {
public:
BookSale(const Book &b, float price, int quantity);
int get_quantity() const;
friend std::ostream& operator<<(std::ostream &out, const BookSale &item);
private:
Book book_info;
float sale_price; // Selling price
int quantity_sold; // Number of copies sold
float total_revenue; // Revenue from sales
};
BookSale::BookSale(const Book &b, float price, int quantity):
book_info{b}, sale_price(price), quantity_sold{quantity} {
total_revenue = quantity_sold * sale_price;
}
int BookSale::get_quantity() const {
return quantity_sold;
}
std::ostream& operator<<(std::ostream &out, const BookSale &item) {
out << std::left;
out << item.book_info << endl
<< setw(15) << "Price:" << item.sale_price << endl
<< setw(15) << "Quantity:" << item.quantity_sold << endl
<< setw(15) << "Revenue:" << item.total_revenue;
return out;
}
book.hpp
#pragma once
#include <string>
#include <iostream>
#include <iomanip>
using std::string;
using std::ostream;
using std::endl;
using std::setw;
using std::left;
class Book {
public:
Book(const string &title, const string &author, const string &translator,
const string &isbn, float price);
friend ostream& operator<<(ostream &out, const Book &book);
private:
string title; // Book title
string author; // Author name
string translator; // Translator name
string isbn; // ISBN number
float price; // List price
};
Book::Book(const string &title, const string &author, const string &translator,
const string &isbn, float price) {
this->title = title;
this->author = author;
this->translator = translator;
this->isbn = isbn;
this->price = price;
}
ostream& operator<<(ostream &out, const Book &book) {
out << left;
out << setw(15) << "Title:" << book.title << endl
<< setw(15) << "Author:" << book.author << endl
<< setw(15) << "Translator:" << book.translator << endl
<< setw(15) << "ISBN:" << book.isbn << endl
<< setw(15) << "Price:" << book.price;
return out;
}
Task 3: Virtual Pet Simulation
This task demonstrates polymorphism through a virtual pet simulation:
virtual_pets.hpp
#pragma once
#include<string>
using std::string;
// Base class for robotic pets
class RoboticPet{
public:
RoboticPet(const string &name): pet_name{name} {}
string get_name() const {
return pet_name;
}
virtual string make_sound() const = 0;
private:
string pet_name;
};
// Robotic cat class
class RoboticCat: public RoboticPet{
public:
RoboticCat(const string &name): RoboticPet{name} {}
string make_sound() const override {
return "meow~";
}
};
// Robotic dog class
class RoboticDog: public RoboticPet{
public:
RoboticDog(const string &name): RoboticPet{name} {}
string make_sound() const override {
return "woof woof~";
}
};
main.cpp
#include <iostream>
#include <vector>
#include "virtual_pets.hpp"
void test_pets() {
using namespace std;
vector<RoboticPet*> pets;
pets.push_back(new RoboticCat("Whiskers"));
pets.push_back(new RoboticDog("Buddy"));
for(auto &pet: pets)
cout << pet->get_name() << " says " << pet->make_sound() << endl;
}
int main() {
test_pets();
}
Task 4: Movie Database
This task implements a movie database with sorting capabilities:
movie.hpp
#pragma once
#include<string>
#include<iostream>
#include<iomanip>
using std::string;
using std::istream;
using std::ostream;
using std::setw;
using std::left;
class Movie {
public:
Movie(const string &title = "", const string &director = "",
const string &country = "", const int &year = 0);
friend istream& operator>>(istream &is, Movie &movie) {
cout << "Enter title: ";
is >> movie.title;
cout << "Enter director: ";
is >> movie.director;
cout << "Enter production country: ";
is >> movie.country;
cout << "Enter release year: ";
is >> movie.release_year;
return is;
}
friend ostream& operator<<(ostream &os, const Movie &movie) {
os << left << setw(20) << movie.title
<< setw(20) << movie.director
<< setw(20) << movie.country
<< setw(10) << movie.release_year;
return os;
}
int get_year() const {
return release_year;
}
private:
string title;
string director;
string country;
int release_year;
};
Movie::Movie(const string &title, const string &director,
const string &country, const int &year) {
this->title = title;
this->director = director;
this->country = country;
this->release_year = year;
}
bool compare_by_year(const Movie &a, const Movie &b) {
return a.get_year() < b.get_year();
}
main.cpp
#include "movie.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
void process_movies() {
using namespace std;
int movie_count;
cout << "Enter number of movies: ";
cin >> movie_count;
cout << "Enter " << movie_count << " movie records" << endl;
vector<Movie> movie_collection;
for(int i = 0; i < movie_count; ++i) {
Movie m;
cout << string(20, '-') << "Movie " << i+1 << " Entry" << string(20, '-') << endl;
cin >> m;
movie_collection.push_back(m);
}
// Sort by release year
sort(movie_collection.begin(), movie_collection.end(), compare_by_year);
cout << string(20, '=') << "Movie Database (by Release Year)" << string(20, '=') << endl;
cout << left << setw(20) << "Title" << setw(20) << "Director"
<< setw(20) << "Country" << setw(10) << "Year" << endl;
cout << string(70, '-') << endl;
for(auto &m: movie_collection)
cout << m << endl;
}
int main() {
process_movies();
}
Task 5: Complex Number Template
This task implements a tempalte class for complex numbers:
complex_number.hpp
#pragma once
#include<iostream>
#include<cmath>
using std::ostream;
using std::istream;
template<typename T>
class ComplexNumber {
public:
ComplexNumber(const T &r = 0, const T &i = 0): real_part{r}, imag_part{i} {}
ComplexNumber operator +=(const ComplexNumber &c) {
real_part += c.real_part;
imag_part += c.imag_part;
return *this;
}
friend ComplexNumber operator+(const ComplexNumber &c1, const ComplexNumber &c2) {
return ComplexNumber<T>(c1.real_part + c2.real_part, c1.imag_part + c2.imag_part);
}
friend bool operator==(const ComplexNumber c1, const ComplexNumber c2) {
return c1.real_part == c2.real_part && c2.imag_part == c1.imag_part;
}
friend ostream &operator<<(ostream &out, const ComplexNumber &c) {
if(c.imag_part >= 0)
out << c.real_part << "+" << c.imag_part << "i";
else
out << c.real_part << "-" << -c.imag_part << "i";
return out;
}
friend istream &operator>>(istream &in, ComplexNumber &c) {
in >> c.real_part >> c.imag_part;
return in;
}
T get_real() const { return real_part; }
T get_imag() const { return imag_part; }
private:
T real_part;
T imag_part;
};
main.cpp
#include "complex_number.hpp"
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::boolalpha;
void test_int_complex() {
ComplexNumber<int> c1(2, -5), c2(c1);
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
cout << "c1 + c2 = " << c1 + c2 << endl;
c1 += c2;
cout << "c1 = " << c1 << endl;
cout << boolalpha << (c1 == c2) << endl;
}
void test_double_complex() {
ComplexNumber<double> c1, c2;
cout << "Enter c1 and c2 (real and imaginary parts): ";
cin >> c1 >> c2;
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
cout << "c1.real = " << c1.get_real() << endl;
cout << "c1.imag = " << c1.get_imag() << endl;
}
int main() {
cout << "ComplexNumber template test with integers: " << endl;
test_int_complex();
cout << endl;
cout << "ComplexNumber template test with doubles: " << endl;
test_double_complex();
}
Task 6: Banking System
This task implements a banking system with inheritance and polymorphism:
banking_system.cpp
#include "account.h"
#include <cmath>
#include <iostream>
using namespace std;
double Account::total_balance = 0;
Account::Account(const Date& date, const string& id) : account_id(id), balance(0) {
date.show();
cout << "\t#" << account_id << " created" << endl;
}
void Account::record(const Date& date, double amount, const string& desc) {
amount = floor(amount * 100 + 0.5) / 100;
balance += amount;
total_balance += amount;
date.show();
cout << "\t#" << account_id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
}
void Account::display() const {
cout << account_id << "\tBalance: " << balance;
}
void Account::error(const string& msg) const {
cout << "Error(#" << account_id << "): " << msg << endl;
}
SavingsAccount::SavingsAccount(const Date& date, const string& id, double rate)
: Account(date, id), interest_rate(rate), acc(date, 0) {}
void SavingsAccount::deposit(const Date& date, double amount, const string& desc) {
record(date, amount, desc);
acc.change(date, get_balance());
}
void SavingsAccount::withdraw(const Date& date, double amount, const string& desc) {
if (amount > get_balance()) {
error("insufficient funds");
}
else {
record(date, -amount, desc);
acc.change(date, get_balance());
}
}
void SavingsAccount::settle(const Date& date) {
if (date.getMonth() == 1) {
double interest = acc.get_sum(date) * interest_rate / (date - Date(date.getYear() - 1, 1, 1));
if (interest != 0) record(date, interest, "interest");
acc.reset(date, get_balance());
}
}
CreditAccount::CreditAccount(const Date& date, const string& id, double credit_limit,
double rate, double annual_fee)
: Account(date, id), credit_limit(credit_limit), interest_rate(rate),
annual_fee(annual_fee), acc(date, 0) {}
void CreditAccount::deposit(const Date& date, double amount, const string& desc) {
record(date, amount, desc);
acc.change(date, get_debt());
}
void CreditAccount::withdraw(const Date& date, double amount, const string& desc) {
if (amount - get_balance() > credit_limit) {
error("exceeds credit limit");
}
else {
record(date, -amount, desc);
acc.change(date, get_debt());
}
}
void CreditAccount::settle(const Date& date) {
double interest = acc.get_sum(date) * interest_rate;
if (interest != 0) record(date, interest, "interest");
if (date.getMonth() == 1) record(date, -annual_fee, "annual fee");
acc.reset(date, get_debt());
}
void CreditAccount::display() const {
Account::display();
cout << "\tAvailable credit: " << get_available_credit();
}
account.h
#pragma once
#include "date.h"
#include "accumulator.h"
#include <string>
using std::string;
class Account {
private:
string account_id;
double balance;
static double total_balance;
protected:
Account(const Date& date, const string& id);
void record(const Date& date, double amount, const string& desc);
void error(const string& msg) const;
public:
const string& get_id() { return account_id; }
double get_balance() const { return balance; }
static double get_total() { return total_balance; }
virtual void deposit(const Date& date, double amount, const string& desc) = 0;
virtual void withdraw(const Date& date, double amount, const string& desc) = 0;
virtual void settle(const Date& date) = 0;
virtual void display() const;
};
class SavingsAccount : public Account {
private:
Accumulator acc;
double interest_rate;
public:
SavingsAccount(const Date& date, const string& id, double rate);
double get_rate() const { return interest_rate; }
void deposit(const Date& date, double amount, const string& desc);
void withdraw(const Date& date, double amount, const string& desc);
void settle(const Date& date);
};
class CreditAccount : public Account {
private:
Accumulator acc;
double credit_limit;
double interest_rate;
double annual_fee;
double get_debt() const {
double balance = get_balance();
return (balance < 0 ? balance : 0);
}
public:
CreditAccount(const Date& date, const string& id, double credit, double rate, double fee);
double get_credit_limit() const { return credit_limit; }
double get_interest_rate() const { return interest_rate; }
double get_annual_fee() const { return annual_fee; }
double get_available_credit() const {
if (get_balance() < 0) return credit_limit + get_balance();
else return credit_limit;
}
void deposit(const Date& date, double amount, const string& desc);
void withdraw(const Date& date, double amount, const string& desc);
void settle(const Date& date);
void display() const;
};
accumulator.h
#pragma once
#include "date.h"
class Accumulator {
private:
Date last_date;
double value;
double sum;
public:
Accumulator(const Date& date, double value)
: last_date(date), value(value), sum{ 0 } {}
double get_sum(const Date& date) const {
return sum + value * (date - last_date);
}
void change(const Date& date, double value) {
sum = get_sum(date);
last_date = date;
this->value = value;
}
void reset(const Date& date, double value) {
last_date = date;
this->value = value;
sum = 0;
}
};
date.h
#pragma once
class Date {
private:
int year;
int month;
int day;
int total_days;
public:
Date(int year, int month, int day);
int getYear() const { return year; }
int getMonth() const { return month; }
int getDay() const { return day; }
int getMaxDay() const;
bool isLeapYear() const {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
void show() const;
int operator-(const Date& date) const {
return total_days - date.total_days;
}
};
main.cpp
#include "account.h"
#include <iostream>
using namespace std;
int main() {
Date current_date(2008, 11, 1);
SavingsAccount savings1(current_date, "S3755217", 0.015);
SavingsAccount savings2(current_date, "02342342", 0.015);
CreditAccount credit(current_date, "C5392394", 10000, 0.0005, 50);
Account* accounts[] = { &savings1, &savings2, &credit };
const int account_count = sizeof(accounts) / sizeof(Account*);
cout << "(d)eposit (w)ithdraw (s)how (c)hange day (n)ext month (e)xit" << endl;
char command;
do {
current_date.show();
cout << "\tTotal: " << Account::get_total() << "\tcommand> ";
int index, day;
double amount;
string description;
cin >> command;
switch (command) {
case 'd':
cin >> index >> amount;
getline(cin, description);
accounts[index]->deposit(current_date, amount, description);
break;
case 'w':
cin >> index >> amount;
getline(cin, description);
accounts[index]->withdraw(current_date, amount, description);
break;
case 's':
for (int i = 0; i < account_count; i++) {
cout << "[" << i << "]";
accounts[i]->display();
cout << endl;
}
break;
case 'c':
cin >> day;
if (day < current_date.getDay()) {
cout << "You cannot specify a previous day";
}
else if (day > current_date.getMaxDay()) {
cout << "Invalid day";
}
else {
current_date = Date(current_date.getYear(), current_date.getMonth(), day);
}
break;
case 'n':
if (current_date.getMonth() == 12) {
current_date = Date(current_date.getYear() + 1, 1, 1);
}
else {
current_date = Date(current_date.getYear(), current_date.getMonth() + 1, 1);
}
for (int i = 0; i < account_count; i++) {
accounts[i]->settle(current_date);
}
break;
}
} while (command != 'e');
return 0;
}