Problem C: 來開個書店吧
Description
某出版社可出版圖書和錄音帶。其中圖書按照每頁的價格乘以頁數進行定價,錄音帶根據每10分鐘的價格乘以錄音帶錄音的分鐘數進行定價。請定義Publicatioin、Book、Tape以及BookStore四個類。其中:
1. Publication類:
1)資料成員double price表示單價(對于書,是每頁的價格;對于錄音帶,是每10分鐘錄音的價格)。
2)資料成員int length表示出版物的長度,對于書,是頁數;對于錄音帶, 是分鐘數。
3)成員函數getTotalPrice()用于傳回一個出版物的定價。
4)構造函數Publication(double, int)用于構造一個出版物。
5)成員函數double getPrice() const和int getLength()用于傳回出版物的單價及長度。
6)析構函數。
2. Book類是Publication的子類。
1)構造函數Book(double,int)。
2)重寫父類的getTotalPrice傳回定價,定價為單價乘以長度(即頁數)。
3)析構函數。
3. Tape是Publication的子類:
1)構造函數Tape(double,int)。
2)重寫父類的getTotalPrice傳回定價。注意:price屬性是每10分鐘錄音的單價,而錄音帶的長度不一定是10的整數倍。計算定價時,不足10分鐘部分,按照10分鐘計算。
3)析構函數。
4.BookStore是書店,具有資料成員Publications **pubs,是書店擁有的出版物清單;int num表示書店擁有的出版物數量。成員函數int getNumOfBook()和int getNumOfTape()分别計算書店中擁有的Book和Tape的數量。該類已經在appcode code中給出。
Input
輸入分多行。
第一行是整數M>0,表示有M個測試用例。
每個測試占一行,分為三部分:第一部分是出版物類型(B表示Book,T表示Tape)、單價和數量(頁數或分鐘數)。
Output
見樣例。
HINT
使用typeid判斷對象指針指向的實際對象的類型。
#include <iostream>
#include <iomanip>
#include <typeinfo>
#include <cstdio>
using namespace std;
class Publication {
protected:
double price;
int length;
public:
virtual double getTotalPrice() { return 0.0; }
virtual double getPrice() const { return price; }
virtual int getLength() const { return length; }
Publication(double x, int y) : price(x), length(y) {
cout << "Call Publication's constructor!" << endl;
}
virtual ~Publication() {
cout << "Call Publication's de-constructor!" << endl;
}
};
class Book : public Publication{
public:
Book(double x, int y) : Publication(x, y) {
cout << "Call Book's constructor!" << endl;
}
double getTotalPrice() { return price*length; }
~Book() {
cout << "Call Book's de-constructor!" << endl;
}
};
class Tape : public Publication {
public:
Tape(double x, int y) : Publication(x, y) {
cout << "Call Tape's constructor!" << endl;
}
double getTotalPrice() {
int len = length;
if (len % 10) {
len = length / 10 + 1;
}
else {
len = length / 10;
}
return price*len;
}
~Tape() {
cout << "Call Tape's de-constructor!" << endl;
}
};
class BookStore
{
private:
Publication **pubs;
int num;
public:
BookStore(Publication **p, int n)
{
pubs = new Publication*[n];
num = n;
for (int i = 0; i < n; i++)
{
if (typeid(*(p[i])) == typeid(Book))
{
pubs[i] = new Book(p[i]->getPrice(), p[i]->getLength());
}
else
{
pubs[i] = new Tape(p[i]->getPrice(), p[i]->getLength());
}
}
}
int getNumOfBook()
{
int c = 0;
for (int i = 0; i < num; i++)
{
if (typeid(*(pubs[i])) == typeid(Book))
c++;
}
return c;
}
int getNumOfTape()
{
int c = 0;
for (int i = 0; i < num; i++)
{
if (typeid(*(pubs[i])) == typeid(Tape))
c++;
}
return c;
}
~BookStore()
{
for (int i = 0; i < num; i++)
{
delete pubs[i];
}
delete[] pubs;
cout<<"Call BookStore's de-constructor!\n";
}
};
int main()
{
int cases, date;
char type;
double total,price;
Publication **pub;
cin>>cases;
pub = new Publication*[cases];
for (int i = 0; i < cases; i++)
{
cin>>type>>price>>date;
switch(type)
{
case 'B':
pub[i] = new Book(price,date);
break;
case 'T':
pub[i] = new Tape(price,date);
break;
}
}
BookStore bookStore(pub, cases);
cout<<"There are "<<bookStore.getNumOfBook()<<" books and "<<bookStore.getNumOfTape()<<" tapes.";
total = 0;
for (int i = 0; i < cases; i++)
{
total += pub[i] -> getTotalPrice();
}
cout<<" Their total price is "<<setprecision(2)<<fixed<<total<<"."<<endl;
for (int i = 0; i < cases; i++)
{
delete pub[i];
}
delete[] pub;
return 0;
}