NO IMAGE

c Primer Plus(習題14.1)

//書上的測試檔案,相當於客戶的使用說明書
//對於書上那個Pair物件,不認真的人都懷疑是否學過
//竟然是一個模板,這道題目想了很久很久,還是沒思路
//看網上的習題,才學會了模仿,總之還是書上沒完全就看懂,才會出現這種問題
//兩題一樣的測試檔案
#include<iostream>
#include"winec.h"
int main()
{
using std::cout;
using std::endl;
using std::cin;
cout << "Enter name of wine: ";
char lab[50];
cin.getline(lab, 50);
cout << "Enter number of years: ";
int yrs;
cin >> yrs;
Wine holding(lab,yrs);
holding.GetBottles();
holding.Show();
const int YRS = 3;
int y[YRS] = { 1993,1995,1998 };
int b[YRS] = { 48,60,72 };
Wine more("Gushing Grape Red", YRS, y, b);
more.Show();
cout << "Total bottles for " << more.Label()
<< ": " << more.sum() << endl;
cout << "Bye!\n";
return 0; 
}
#pragma once
#pragma execution_character_set("utf-8")
//本檔案為utf-8編碼格式
#ifndef PORT_H
#define PORT_H
#include<iostream>
using namespace std;
class Port
{
private:
char *brand;
char style[20];			//ie.,tawny,ruby,vintage
int bottles;
public:
Port(const char*br = "none", const char *st = "none", int b = 0);
Port(const Port&p);
virtual ~Port() { delete[] brand; }
Port&operator=(const Port&p);
Port&operator =(int b);				// add b to bottles
Port&operator-=(int b);
virtual void Show()const;
friend ostream& operator<<(ostream&os, const Port&p);
protected:
int BottleCount()const { return bottles; }
};
class VintagePort :public Port
{
private:
char *nickname;
int year;
public:
VintagePort();
VintagePort(const char*nn, int y, const char*br, int b);
VintagePort(const VintagePort &vp);
~VintagePort() { delete[]nickname; };
VintagePort&operator=(const VintagePort&vp);
virtual void Show()const;
friend ostream&operator<<(ostream&os, const VintagePort&pt);
};
#endif // !PORT_H

#include"port.h"
using std::cout;
using std::endl;
//Port methods
Port::Port(const char*br, const char *st, int b)
{
brand = new char[std::strlen(br)   1];
std::strcpy(brand, br);
std::strcpy(style, st);
bottles = b;
}
Port::Port(const Port&p)
{
brand = new char[std::strlen(p.brand)   1];
std::strcpy(brand, p.brand);
std::strcpy(style, p.style);
bottles = p.bottles;
}
Port&Port::operator=(const Port&p)
{
if (this == &p)
return *this;
delete[]brand;
brand = new char[std::strlen(p.brand)   1];
std::strcpy(brand, p.brand);
std::strcpy(style, p.style);
bottles = p.bottles;
return *this;
}
Port&Port::operator =(int b)
{
bottles  = b;
return *this;
}
Port&Port::operator-=(int b)
{
bottles -= b;
return *this;
}
//out put methods
void Port::Show()const
{
cout << "Brand: " << brand << endl
<< "Kind: " << style << endl
<< "Bottles: " << bottles << endl;
}
ostream& operator<<(ostream&os, const Port&p)
{
os << p.brand << " , " << p.style << " , " << p.bottles;
return os;
}
//VintagePort methods 
VintagePort::VintagePort()
{
nickname = new char[1];
nickname = nullptr;
year = 0;
}
VintagePort::VintagePort(const char*br,int b, const char*nn, int y):Port(br,"vintage",b)
{
nickname = new char[std::strlen(nn)   1];
std::strcpy(nickname, nn);
year = y;
}
VintagePort::VintagePort(const VintagePort &vp):Port(vp)
{
delete[]nickname;
nickname = new char[std::strlen(vp.nickname)   1];
std::strcpy(nickname, vp.nickname);
year = vp.year;
}
VintagePort&VintagePort::operator=(const VintagePort&vp)
{
if (this == &vp)
return *this;
delete[]nickname;
nickname = new char[std::strlen(vp.nickname)   1];
std::strcpy(nickname, vp.nickname);
year = vp.year;
return *this;
}
void VintagePort::Show()const
{
Port::Show();					//呼叫基類的方法,用來顯示基類部分
cout << "Nick name: " << nickname << endl
<< "Year: " << year << endl;
}
ostream&operator<<(ostream&os, const VintagePort&pt)
{
os << (const Port&)pt;
os << " , " << pt.nickname << " , ";
return os;
}

c Primer Plus(習題14.2)

#pragma once
#pragma execution_character_set("utf-8")
//本檔案為utf-8編碼格式
#ifndef QUEUETP_H
#define QUEUETP_H
#include<iostream>
template <class T>
//一個簡單的佇列,別人的程式碼
class queuetp
{
private:
T  *data;
const static int MAX = 10;			///佇列的最大數量
int top;
public:
queuetp() { top = 0; data = new T[MAX]; }
queuetp(int len) { top = 0; data = new T[len]; }		//
//~queuetp(){delete []data;},外面顯示呼叫delete[],不然就會痛兩次delete
bool Push(T item);
bool Pop();
T&front()const;
T&rear()const ;
bool isfull() { return top == MAX; };
bool isempty() { return top == 0; }
};
template <class T>
bool queuetp<T>::Push(T item)
{
if (isfull())
return false;
for (int i = top; i > 0; --i)
data[i] = data[i - 1];			//加到佇列的末尾
data[0] = item;						//
top;
return true;
}
template <class T>
bool queuetp<T>::Pop()
{
if (isempty())
return false;
--top;
return true;
}
template <class T>
T&queuetp<T>::rear()const
{
return data[0];
}
template <class T>
T&queuetp<T>::front()const
{
return data[top-1];
}
#endif // !QUEUETP_H
#pragma once
#pragma execution_character_set("utf-8")
//本檔案為utf-8編碼格式
//書上的一個多重繼承事例,
#ifndef WORKERMI_H_  
#define WORKERMI_H_  
#include <string>  
class Worker
{
private:
std::string fullname;
long id;
protected:
virtual void Data() const;
virtual void Get();
public:
Worker() : fullname("no one"), id(0L) {}
Worker(const std::string &s, long n) :fullname(s), id(n) {}
virtual ~Worker() = 0;
virtual void Set() = 0;
virtual void Show() const = 0;
};
class Waiter : virtual public Worker
{
private:
int panache;
protected:
void Data() const;
void Get();
public:
Waiter() : Worker(), panache(0) {}
Waiter(const std::string &s, long n, int p = 0) : Worker(s, n), panache(p) {}
Waiter(const Worker &wk, int p = 0) : Worker(wk), panache(p) {}
void Set();
void Show() const;
};
class Singer : virtual public Worker
{
protected:
enum { other, alto, contralto, soprano, bass, baritone, tenor };
enum { Vtypes = 7 };
void Data() const;
void Get();
private:
static char *pv[Vtypes];
int voice;
public:
Singer() : Worker(), voice(other) {}
Singer(const std::string &s, long n, int v = other) : Worker(s, n), voice(v) {}
Singer(const Worker &wk, int v = other) : Worker(wk), voice(v) {}
void Set();
void Show() const;
};
class SingingWaiter : public Singer, public Waiter
{
protected:
void Data() const;
void Get();
public:
SingingWaiter() {}
SingingWaiter(const std::string &s, long n, int p = 0, int v = other) 
: Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {}
SingingWaiter(const Worker &wk, int p = 0, int v = other) 
: Worker(wk), Waiter(wk, p), Singer(wk, v) {}
SingingWaiter(const Waiter &wt, int v = other) 
: Worker(wt), Waiter(wt), Singer(wt, v) {}
SingingWaiter(const Singer &wt, int p = 0) 
: Worker(wt), Waiter(wt, p), Singer(wt) {}
void Set();
void Show() const;
};
#endif  
//書上的原始碼,不解釋
#include "workermi.h"  
#include <iostream>  
using std::cout;
using std::cin;
using std::endl;
Worker::~Worker() {}
void Worker::Data() const
{
cout << "Name: " << fullname << endl;
cout << "Emplyee ID: " << id << endl;
}
void Worker::Get()
{
getline(cin, fullname);
cout << "Enter worker's ID: ";
cin >> id;
while (cin.get() != '\n')
continue;
}
void Waiter::Set()
{
cout << "Enter waiter's name: ";
Worker::Get();
Get();
}
void Waiter::Show() const
{
cout << "Category: waiter\n";
Worker::Data();
Data();
}
void Waiter::Data() const
{
cout << "Panache rating: " << panache << endl;
}
void Waiter::Get()
{
cout << "Enter waiter's panache rating: ";
cin >> panache;
while (cin.get() != '\n')
continue;
}
char *Singer::pv[Singer::Vtypes] = { "other", "alto", "contralto", "soprano", "bass", "baritone", "tenor" };
void Singer::Set()
{
cout << "Enter singer's name: ";
Worker::Get();
Get();
}
void Singer::Show() const
{
cout << "Category: singer\n";
Worker::Data();
Data();
}
void Singer::Data() const
{
cout << "Vocal range: " << pv[voice] << endl;
}
void Singer::Get()
{
cout << "Enter number for singer's vocal range:\n";
int i;
for (i = 0; i < Vtypes;   i)
{
cout << i << ": " << pv[i] << "   ";
if (i % 4 == 3)
cout << endl;
}
if (i % 4 != 0)
cout << '\n';
cin >> voice;
while (cin.get() != '\n')
continue;
}
void SingingWaiter::Data() const
{
Singer::Data();
Waiter::Data();
}
void SingingWaiter::Get()
{
Waiter::Get();
Singer::Get();
}
void SingingWaiter::Set()
{
cout << "Enter singing waiter's name: ";
Worker::Get();
Get();
}
void SingingWaiter::Show() const
{
cout << "Category: singing waiter\n";
Worker::Data();
Data();
}
//借鑑別人的程式碼,不是原創
#include <iostream>  
#include <cstring>  
#include "workermi.h"  
#include "queuetp.h"  
const int SIZE = 2;
int main()
{
using std::cin;
using std::cout;
using std::endl;
using std::strchr;
queuetp<Worker *> lolas(SIZE);
int ct;
for (ct = 0; ct < SIZE;   ct)
{
char choice;
cout << "Enter the employee category: \n"
<< "w: waiter s: singer "
<< "t: singing waiter q: quit\n";
cin >> choice;
while (strchr("wstq", choice) == NULL)
{
cout << "Please enter a w, s, t, or q: ";
cin >> choice;
}
if (choice == 'q')
break;
switch (choice)
{
case 'w': lolas.Push(new Waiter);
break;
case 's': lolas.Push(new Singer);
break;
case 't': lolas.Push(new SingingWaiter);
break;
}
cin.get();
lolas.rear()->Set();
}
cout << "\nHere is your staff:\n";
int i;
for (i = 0; i < ct;   i)
{
cout << endl;
lolas.front()->Show();
lolas.Push(lolas.front());
lolas.Pop();
}
for (i = 0; i < ct;   i)
{
delete lolas.front();
lolas.Pop();
}
cout << "Bye";
return 0;
}

c Primer Plus(習題14.4)

//改寫的一個測試程式,很簡單的測試
#include <iostream>  
#include "myperson.h"  
const int SIZE = 3;
int main()
{
using std::cin;
using std::cout;
using std::endl;
Person *lolas[SIZE];
int ct;
for (ct = 0; ct < SIZE;   ct)
{
char choice;
cout << "You are a : \n"
<< "b: BadDude p: PokerPlayer "
<< "g: Gunslinger q: quit\n";
cin >> choice;
while (strchr("bpgq", choice) == NULL)
{
cout << "Please enter b,p,gor q: ";
cin >> choice;
}
if (choice == 'q')
break;
switch (choice)
{
case 'b': lolas[ct]=new BadDude;
break;
case 'g': lolas[ct] = new Gunslinger;
break;
case 'p': lolas[ct] = new PokerPlayer;
break;
}
cin.get();
lolas[ct]->Set();			//呼叫類的設定方法
}
if (ct>0)
{
cout << "\nHere is your staff:\n";
int i;
for (i = 0; i < ct;   i)
{
cout << endl;
lolas[i]->Show();
}
for (i = 0; i < ct;   i)
{
delete lolas[i];
}
}
cout << "Bye!\n";
return 0;
}

#pragma once
#pragma execution_character_set("utf-8")
//本檔案為utf-8編碼格式
//書上的習題14.4標頭檔案,設計一個多重繼承的類
#ifndef MYPERSON_H
#define MYPERSON_H
#include<string>
#include<iostream>
#include<cctype>
using std::string;
class Person			//虛基類
{
private:
string fname;
string lname;
protected:
virtual void Data() const;
virtual void Get();
public:
Person() :fname("no name"), lname("no name") {};
Person(const char*fn, const char*ln) :fname(fn), lname(ln) {};
virtual ~Person()=0{};
virtual void Show()const=0;
virtual void Set() = 0 {};			//兩次做作業都是因為這裡沒加花括號導致連結錯誤,
//可是書上也沒加啊
};
class Gunslinger:virtual public Person			
{
private:
double time;					//拔槍時間
int symbolcount;				//刻痕數
protected:
double DrawTime() { return time; }
virtual void Data() const;
virtual void Get();
public:
Gunslinger() :Person(), time(0.0), symbolcount(0) {};
Gunslinger(const char*fn, const char*ln, const double t, const int c)
:Person(fn, ln), time(t), symbolcount(c) {};
Gunslinger(const Person&p,const double t,const int c)
:Person(p),time(t), symbolcount(c) {};
virtual void Show()const;
void Set();
};
class Card						//撲克牌的類
{
private:
string color;				//花色
char number;					//考慮到j,Q,K這種,不應該是純數字
public:
Card(const string &c, const char n) :color(c),number(n) {};
Card():color("NO color"), number('0') {};
string& R_Color() { return color; }						//用來設定花色
char& R_Number() { return number; }						//設定數字
void Report()const { std::cout<<"Poker :" << color
<< " " <<Tou()<< std::endl; }
char Tou()const {
char tem;
return tem = (std::toupper(number));
}		//將撲克牌的數字變成大寫
};
class PokerPlayer:public virtual Person
{
private:
Card value;
protected:
Card &DrawCard() { return value; }
virtual void Data() const;
virtual void Get();
public:
PokerPlayer() :Person(), value("no color", '0') {};
PokerPlayer(const char*fn, const char*ln, const string &c, const char n)
: Person(fn, ln),value(c,n){};
PokerPlayer(const Person&p, const string&c, const char n)
:Person(p), value(c, n) {};
virtual void Show()const;
void Set();
};
//怪事,出現person類show重寫不明確
class BadDude:public PokerPlayer,public Gunslinger
{
protected:
virtual void Data() const;
virtual void Get();
public:
BadDude() {};
BadDude(const char*fn, const char*ln, const double t, const int c,const string &cr, const char n)
:Person(fn, ln),Gunslinger(fn,ln,t,c),PokerPlayer(fn,ln,cr,n){};
BadDude(const Person&p, const double t, const int c, const string &cr, const char n)
:Person(p), Gunslinger(p,t,c), PokerPlayer(p,cr, n) {};
BadDude(const Gunslinger&g, const string &cr, const char n)
:Person(g),Gunslinger(g), PokerPlayer(g,cr, n) {};
BadDude(const PokerPlayer&p, const double t, const int c)
:Person(p), Gunslinger(p, t, c), PokerPlayer(p) {};
double Gdraw(){ return DrawTime(); }
Card& Cdraw() { return DrawCard(); }
void Show()const;
void Set();
};
#endif // !MYPERSONG_H
#include"myperson.h"
using std::cin;
using std::cout;
using std::endl;
//person methods
void Person::Data() const
{
cout << "Name: " << lname << "," << fname << endl;
}
void Person::Get()
{
std::getline(cin, fname);
cout << "Enter last name: ";
std::getline(cin, lname);
}
//Gunslinger methods
void Gunslinger::Set()					//書上的一個元件,防止設定多個基類值
{
cout << "Enter the Gunslinger frist name: ";
Person::Get();
Get();					//呼叫自己的方法
}
void Gunslinger::Get()						//這個用來獲得資料,提示使用者輸入
{
cout << "Enter the pick gun time: ";
cin >> time;
cout << "Enter the symbol count: ";
cin >> symbolcount;
}
void Gunslinger::Show()const			//重新定義的虛方法
{
cout << "Category: Gunslinger\n";
Person::Data();			//顯示基類的資料
Data();					//顯示自己的資料
}
void Gunslinger::Data() const			//資料的顯示
{
cout << "Pick gun time: " << time << endl
<< "Symbolcount: " << symbolcount << endl;
}
//PokerPlayer methods
void PokerPlayer::Set()
{
cout << "Enter PokerPlayer fname: ";
Person::Get();
Get();
}
void PokerPlayer::Data()const
{
value.Report();
}
void PokerPlayer::Get()
{
cout << "Enter poker color: ";
std::getline(cin, value.R_Color());
cout << "Enter poker number: ";
cin >> value.R_Number();
}
void PokerPlayer::Show()const
{
cout << "Category: PokerPlayer\n";
Person::Data();
Data();
}
//BadDude methods
void BadDude::Data() const					//提供顯示的資料
{
Gunslinger::Data();
PokerPlayer::Data();
}
void BadDude::Get()							//獲得資料
{
Gunslinger::Get();
cin.get();					//老問題,混合輸入數字和字元
PokerPlayer::Get();
}
void BadDude::Set()
{
cout << "Enter BadDude frist name: ";
Person::Get();
Get();
}
void BadDude::Show()const
{
cout << "Category: BadDude\n";
Person::Data();			//顯示祖先的資料
Data();
}

c Primer Plus(習題14.5)

//書上的測試小程式檔案
//因為沒有賦值運算子
//宣告為虛的是為了多型的形成
//防止highfink類包含多個absre_emp
//highfink不需要資料部分因為他的直接基類有所需的資料成員
//抽象基類的一個<<方法就可以用於其他派生出來的類
//
#include<iostream>
using namespace std;
#include"emp.h"
int main(void)
{
employee em("Trip", "Harris", "Thumper");
cout << "em" << endl;
em.ShowAll();
manager ma("Amorphia", "Spindragon", "Nuancer", 5);
cout << ma << endl;
ma.ShowAll();
fink fi("Matt", "Oggs", "Oiler", "Juno Barr");
cout << fi << endl;
fi.ShowAll();
highfink hf(ma,"Curly Kew");			//出現要按回車才能繼續執行
hf.ShowAll();
cout << "Press a key for mext phase:\n";
cin.get();
highfink hf2;
hf2.SetAll();
cout << "Using an abstr_emp *pointer:\n";
abstr_emp *tri[4] = { &em,&fi,&hf,&hf2 };
for (int i = 0; i < 4; i  )
tri[i]->ShowAll();
cout << "************Test complete!************\n";
/*abstr_emp tri[4] = { em,fi,hf,hf2 };
for (int i = 0; i < 4; i  )
tri[i].ShowAll();*/
//替換成這個編譯器會報錯,不能宣告抽象類陣列
return 0;
}

#pragma once
#pragma execution_character_set("utf-8")
//本檔案為utf-8編碼格式
//這個標頭檔案屬於14.5題書上提供的多型繼承標頭檔案
#ifndef EMP_H
#define EMP_H
#include<iostream>
#include<string>
using std::string;
class abstr_emp
{
private:
string fname;
string lname;
string job;
public:
abstr_emp() :fname("No name"), lname("no name "), job("no job") {};
abstr_emp(const string&fn, const string&ln, const string &j) :fname(fn)
, lname(ln), job(j) {};
virtual void ShowAll()const;
virtual void SetAll();
friend std::ostream&operator<<(std::ostream &os, const abstr_emp&e);
virtual ~abstr_emp() = 0 {};//這裡少了{}會報錯,連結錯誤一大堆
};
class employee :public abstr_emp
{
public:
employee(const string &fn, const string&ln, const string&j) :abstr_emp(fn, ln, j) {};
employee() :abstr_emp() {};
virtual void ShowAll()const { abstr_emp::ShowAll(); };
virtual void SetAll() { abstr_emp::SetAll(); };
};
class manager:virtual public abstr_emp
{
public:
manager() :abstr_emp(), inchargeof(0){};
manager(const string &fn, const string &ln,
const string &j, int ico = 0) :abstr_emp(fn, ln, j),inchargeof(ico){};
manager(const abstr_emp&e, int ico) :abstr_emp(e), inchargeof(ico) {};
manager(const manager&m);
virtual void ShowAll()const;
virtual void SetAll();
protected:
int InChargeOf()const { return inchargeof; }	//outut method
int &InChargeOf() { return inchargeof; }		//input method
private:
int inchargeof;
};
class fink :virtual public abstr_emp
{
private:
string reportsto;
protected:
const string ReportsTo()const { return reportsto; }
string &ReportsTo(){ return reportsto; }
public:
fink() :abstr_emp(), reportsto ("null"){};
fink(const string &fn, const string &ln,
const string &j, const string &rpo) :abstr_emp(fn, ln, j), reportsto(rpo) {};
fink(const abstr_emp&e, const string &rpo):abstr_emp(e), reportsto(rpo) {};
fink(const fink&e);
virtual void ShowAll()const;
virtual void SetAll();
};
class highfink :public manager, public fink
{
public:
highfink(){};				//顯式呼叫基類建構函式
highfink(const string &fn, const string &ln,
const string &j, const string &rpo, int ico)
:abstr_emp(fn, ln, j), fink(fn, ln, j, rpo), manager(fn, ln, j, ico) {};
highfink(const abstr_emp&e, const string &rpo, int ico)
:abstr_emp(e), fink(e, rpo), manager(e, ico) {};
highfink(const fink &f, int ico) 
:abstr_emp(f), fink(f), manager(f, ico) {};
highfink(const manager &m, const string &rpo) 
:abstr_emp(m), manager(m), fink(m, rpo) {};
highfink(const highfink&h)
:abstr_emp(h), manager(h), fink(h) {};
virtual void ShowAll()const;
virtual void SetAll();
};
#endif // !EMP_H

#include"emp.h"
using std::cout;
using std::endl;
using std::cin;
//abstr_emp methods
void abstr_emp::ShowAll()const
{
cout << "Name: " << lname << " " << fname << endl
<< "Job: " << job<<endl;
}
//設定各成員的值
void abstr_emp::SetAll()
{
cout << "Enter frist name: ";
std::getline(cin,fname);
cout << "Enter last name: ";
std::getline(cin, lname);
cout << "Job: ";
std::getline(cin, job);
}
//only display name
std::ostream&operator<<(std::ostream &os, const abstr_emp&e)
{
os << "Name: " << e.lname << " , " << e.fname;
return os; 
}
//manage methods
manager::manager(const manager&m):abstr_emp(m)	//copy construction function
{
inchargeof = m.inchargeof;
}
void manager::ShowAll()const
{
abstr_emp::ShowAll();
cout << "Inchargeof: " << inchargeof << endl;
}
void manager::SetAll()
{
abstr_emp::SetAll();
cout<< "Enter the inchangeof count: ";
cin>> inchargeof;
while (cin.get() != '\n')
continue;
}
//fink methods
fink::fink(const fink&e) :abstr_emp(e)
{
reportsto = e.reportsto;
}
void fink::ShowAll()const
{
abstr_emp::ShowAll();
cout << "Reportsto: " << reportsto << endl;
}
void fink::SetAll()
{
cout << "Enter the reportsto: ";
std::getline(cin, reportsto);
while (cin.get() != '\n')
continue;
}
//highlink methods
void highfink::ShowAll()const
{
abstr_emp::ShowAll();		//使用直接基類的保護方法進行輸出
cout << "Inchargeof: " << manager::InChargeOf() << endl;
cout << "Reportsto: " << fink::ReportsTo() << endl;
}
void highfink::SetAll()
{
abstr_emp::SetAll();
string temp;				//這裡要弄好一點,不然會設定基類兩次,也可以自己
int tem;
cout << "Enter the inchangeof count: ";	//用的是書上那個保護方法,返回引用就可以対值修改
cin >> tem;
cin.get();		//處理換行符
cout << "Enter the reportsto: ";
std::getline(cin, temp);
ReportsTo()=temp;
InChargeOf()=tem;
}