C++Primer Plus筆記——第十三章 類繼承課後程式設計練習答案
阿新 • • 發佈:2018-12-12
目錄
課後程式設計練習
習題1
#include <iostream> #include <cstring> using namespace std; // base class class Cd { char performers[50]; char label[20]; int selections; // number of selections double playtime; // playing time in minutes public: explicit Cd(const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0); virtual ~Cd() {} virtual void Report() const; // reports all CD data }; static void cpStr(char* p_des_txt, const char* p_src_txt, unsigned des_arr_size) { unsigned str_len = strlen(p_src_txt) < des_arr_size - 1 ? strlen(p_src_txt) : des_arr_size - 1; strncpy(p_des_txt, p_src_txt, str_len); p_des_txt[str_len] = '\0'; } Cd::Cd(const char * s1, const char * s2, int n, double x) : selections(n), playtime(x) { cpStr(performers, s1, 50); cpStr(label, s2, 20); } void Cd::Report() const { cout << performers << ", " << label << ", " << selections << "," << playtime << flush; } class Classic : public Cd { static const unsigned mk_size = 64; char m_songs[mk_size]; public: Classic(const char* songs_list = "", const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0); virtual void Report() const; // reports all CD data }; Classic::Classic(const char* songs_list, const char * s1, const char * s2, int n, double x) : Cd(s1, s2, n, x) { cpStr(m_songs, songs_list, mk_size); } void Classic::Report() const { Cd::Report(); cout << ", " << m_songs << endl; } void Bravo(const Cd & disk) { disk.Report(); cout << endl; } int main() { Cd c1("Beatles", "Capitol", 14, 35.5); Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C", "Alfred Brendel", "Philips", 2, 57.17); Cd *pcd = &c1; cout << "Using object directly:\n"; c1.Report(); // use Cd method c2.Report(); // use Classic method cout << "Using type cd * pointer to objects:\n"; pcd->Report(); // use Cd method for cd object pcd = &c2; pcd->Report(); // use Classic method for classic object cout << "Calling a function with a Cd reference argument:\n"; Bravo(c1); Bravo(c2); cout << "Testing assignment: "; Classic copy; copy = c2; copy.Report(); }
習題2
#include <iostream> #include <cstring> using namespace std; // base class class Cd { char* performers; char* label; int selections; // number of selections double playtime; // playing time in minutes public: explicit Cd(const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0); Cd(const Cd & d); virtual ~Cd(); virtual void Report() const; // reports all CD data Cd & operator=(const Cd & d); }; static char* cpNewStr(const char* p_src_txt) { unsigned str_len = strlen(p_src_txt); char* p_des_txt = new char[str_len + 1]; strcpy(p_des_txt, p_src_txt); return (p_des_txt); } Cd::Cd(const char * s1, const char * s2, int n, double x) : selections(n), playtime(x) { performers = cpNewStr(s1); label = cpNewStr(s2); } Cd::~Cd() { delete[] performers; delete[] label; } Cd::Cd(const Cd & d) : selections(d.selections), playtime(d.playtime) { performers = cpNewStr(d.performers); label = cpNewStr(d.label); } Cd & Cd::operator=(const Cd & d) { if (&d == this) { return (*this); } delete[] performers; performers = cpNewStr(d.performers); delete[] label; label = cpNewStr(d.label); selections = d.selections; playtime = d.playtime; return (*this); } void Cd::Report() const { cout << performers << ", " << label << ", " << selections << ", " << playtime << flush; } // derive class Classic : public Cd { char* songs; public: explicit Classic(const char* songs_list = "", const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0); Classic(const Classic& classic); virtual ~Classic(); Classic& operator= (const Classic& classic); virtual void Report() const; // reports all CD data }; Classic::Classic(const char* songs_list, const char * s1, const char * s2, int n, double x) : Cd(s1, s2, n, x) { songs = cpNewStr(songs_list); } Classic::Classic(const Classic& classic) : Cd(classic) { songs = cpNewStr(classic.songs); } Classic::~Classic() { delete[] songs; } Classic & Classic::operator= (const Classic& classic) { if (&classic == this) return (*this); Cd::operator=(classic); delete[] songs; songs = cpNewStr(classic.songs); return (*this); } void Classic::Report() const { Cd::Report(); cout << ", " << songs << endl; } void Bravo(const Cd & disk) { disk.Report(); cout << endl; } int main() { Cd c1("Beatles", "Capitol", 14, 35.5); Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C", "Alfred Brendel", "Philips", 2, 57.17); Cd *pcd = &c1; cout << "Using object directly:\n"; c1.Report(); // use Cd method c2.Report(); // use Classic method cout << "Using type cd * pointer to objects:\n"; pcd->Report(); // use Cd method for cd object pcd = &c2; pcd->Report(); // use Classic method for classic object cout << "Calling a function with a Cd reference argument:\n"; Bravo(c1); Bravo(c2); cout << "Testing assignment: "; Classic copy; copy = c2; copy.Report(); }
習題3
/// Test.h #ifndef _Test_H_ #define _Test_H_ #include <iostream> using namespace std; namespace FableGame { class ABC { private: char* label; int rating; public: ABC(const char* l = "null", int r = 0); ABC(const ABC& rs); virtual ~ABC(); ABC& operator=(const ABC& rs); friend std::ostream& operator<<(std::ostream& os, const ABC& rs); virtual void view() = 0; char* getLabel() { return label; } int getRating() { return rating; } }; class baseDMA :public ABC { public: baseDMA(const char* l = "null", int r = 0); baseDMA(const baseDMA& rs); virtual void view(); }; class lacksDMA :public ABC { private: enum { COL_LEN = 40 }; char color[COL_LEN]; public: lacksDMA(const char* c = "blank", const char* l = "null", int r = 0); lacksDMA(const char* c, const ABC& ls); friend std::ostream& operator<<(std::ostream& os, const lacksDMA& ls); virtual void view(); }; class hasDMA : public ABC { private: char * style; public: hasDMA(const char* s = "none", const char* l = "null", int r = 0); hasDMA(const char* s, const ABC& hs); hasDMA(const hasDMA& hs); ~hasDMA(); hasDMA& operator=(const hasDMA& hs); friend std::ostream& operator<<(std::ostream& os, const hasDMA& hs); virtual void view(); }; } #endif // Test.cpp #include "Test.h" #include <iostream> #include <cstdlib> using namespace std; using namespace FableGame; FableGame::ABC::ABC(const char* l /*= "null"*/, int r /*= 0*/) { int size = strlen(l) + 1; label = new char[size]; strcpy_s(label, size, l); rating = r; } FableGame::ABC::ABC(const ABC& rs) { int size = strlen(rs.label) + 1; label = new char[size]; strcpy_s(label, size, rs.label); rating = rs.rating; } FableGame::ABC::~ABC() { delete[] label; } ABC& FableGame::ABC::operator=(const ABC& rs) { if (this == &rs) { return *this; } delete[] label; int size = strlen(rs.label) + 1; label = new char[size]; strcpy_s(label, size, rs.label); rating = rs.rating; return *this; } void FableGame::ABC::view() { cout << "Label: " << getLabel() << endl; cout << "Rating: " << getRating() << endl; } std::ostream& FableGame::operator<<(std::ostream& os, const ABC& rs) { os << "Label: " << rs.label << endl; os << "Rating: " << rs.rating << endl; return os; } FableGame::lacksDMA::lacksDMA(const char* c, const char* l, int r) : ABC(l, r) { strncpy_s(color, c, 39); color[39] = '\0'; } FableGame::lacksDMA::lacksDMA(const char* c, const ABC& rs) :ABC(rs) { strncpy_s(color, c, COL_LEN - 1); color[COL_LEN - 1] = '\0'; } void FableGame::lacksDMA::view() { ABC::view(); cout << "Color: " << color << endl; } std::ostream& FableGame::operator<<(std::ostream& os, const lacksDMA& ls) { os << (const ABC&)ls; os << "Color: " << ls.color << endl; return os; } FableGame::hasDMA::hasDMA(const char* s, const char* l, int r) :ABC(l, r) { style = new char[strlen(s) + 1]; strcpy_s(style, strlen(s) + 1, s); } FableGame::hasDMA::hasDMA(const char* s, const ABC& rs) :ABC(rs) { style = new char[strlen(s) + 1]; strcpy_s(style, strlen(s) + 1, s); } FableGame::hasDMA::hasDMA(const hasDMA& hs) :ABC(hs) { style = new char[strlen(hs.style) + 1]; strcpy_s(style, strlen(hs.style) + 1, hs.style); } FableGame::hasDMA::~hasDMA() { delete[] style; } hasDMA& FableGame::hasDMA::operator=(const hasDMA& hs) { if (this == &hs) { return *this; } ABC::operator=(hs); delete[] style; style = new char[strlen(hs.style) + 1]; strcpy_s(style, strlen(hs.style) + 1, hs.style); return *this; } void FableGame::hasDMA::view() { ABC::view(); cout << "Style: " << style << endl; } std::ostream& FableGame::operator<<(std::ostream& os, const hasDMA& hs) { os << (const ABC&)hs; os << "Style: " << hs.style << endl; return os; } FableGame::baseDMA::baseDMA(const char* l /*= "null"*/, int r /*= 0*/) :ABC(l, r) { } FableGame::baseDMA::baseDMA(const baseDMA& rs) : ABC(rs) { } void FableGame::baseDMA::view() { ABC::view(); } //main.cpp #include <iostream> #include "Test.h" #include <string> using namespace std; using namespace FableGame; const int ARR_SIZE = 3; int main(int argc, const char * argv[]) { ABC* p_ABC[ARR_SIZE]; char temp[40]; int tempnum; int kind; for (int i = 0; i < ARR_SIZE; i++) { cout << "Enter label: "; cin.getline(temp, 40); cout << "Enter Rating: "; cin >> tempnum; cout << "Enter 1 for baseDMA or 2 for lacksDMA or 3 for hasDMA: "; while (cin >> kind && (kind != 1 && kind != 2 && kind != 3)) { cout << "Enter either 1 or 2 or 3: "; } cin.get(); if (kind == 1) { p_ABC[i] = new baseDMA(temp, tempnum); } else if (kind == 2) { char color[40]; cout << "Enter the color: "; cin.getline(color, 40); p_ABC[i] = new lacksDMA(color, temp, tempnum); } else if (kind == 3) { char style[40]; cout << "Enter the style: "; cin.getline(style, 40); p_ABC[i] = new hasDMA(style, temp, tempnum); } } cout << endl; for (int i = 0; i < ARR_SIZE; i++) { p_ABC[i]->view(); cout << endl; } for (int i = 0; i < ARR_SIZE; i++) { delete p_ABC[i]; } cout << "Done." << endl; return 0; }
習題4
#include <iostream>
#include <cstring>
using namespace std;
class Port
{
char * brand;
char style[20]; // i.e., tawny, ruby, vintage
int bottles;
public:
explicit Port(const char * br = "none", const char * st = "none", int b = 0);
Port(const Port & p); // copy constructor
virtual ~Port() { delete[] brand; }
Port & operator=(const Port & p);
virtual void Show() const;
Port & operator+=(int b); // adds b to bottles
Port & operator-=(int b); // subtracts b from bottles, if available
int BottleCount() const { return bottles; }
friend ostream & operator<<(ostream & os, const Port & p);
};
static char* cpNewStr(const char* p_src_txt)
{
unsigned str_len = strlen(p_src_txt);
char* p_des_txt = new char[str_len + 1];
strcpy(p_des_txt, p_src_txt);
return (p_des_txt);
}
static void cpStr(char* p_des_txt, const char* p_src_txt, unsigned des_arr_size)
{
unsigned str_len = strlen(p_src_txt) < des_arr_size - 1 ? strlen(p_src_txt) : des_arr_size - 1;
strncpy(p_des_txt, p_src_txt, str_len);
p_des_txt[str_len] = '\0';
}
Port::Port(const char * br, const char * st, int b)
: brand(cpNewStr(br)), bottles(b)
{
cpStr(style, st, 20);
}
Port::Port(const Port & p)
: brand(cpNewStr(p.brand)), bottles(p.bottles)
{
cpStr(style, p.style, 20);
}
void Port::Show() const
{
cout << "Brand: " << brand << endl
<< "Style: " << style << endl
<< "Bottles: " << bottles << flush;
}
Port & Port::operator=(const Port & p)
{
if (&p == this)
return (*this);
delete[] brand;
brand = cpNewStr(p.brand);
cpStr(style, p.style, 20);
bottles = p.bottles;
return (*this);
}
Port & Port::operator+=(int b)
{
bottles += b;
return (*this);
}
Port & Port::operator-=(int b)
{
bottles -= b;
return (*this);
}
ostream & operator<< (ostream & os, const Port & p)
{
cout << p.brand << ", " << p.style << ", " << p.bottles << flush;
return (os);
}
class VintagePort : public Port // style necessarily = "vintage"
{
char * nickname; // i.e., "The Noble" or "Old Velvet", etc.
int year; // vintage year
public:
explicit VintagePort(const char * br , int b = 0, const char * nn , int y = 0);
VintagePort(const VintagePort & vp);
virtual ~VintagePort() { delete[] nickname; }
VintagePort & operator=(const VintagePort & vp);
virtual void Show() const;
friend ostream & operator<<(ostream & os, const VintagePort & vp);
};
VintagePort::VintagePort(const char * br, int b, const char * nn, int y)
: Port(br, "vintage", b), nickname(cpNewStr(nn)), year(y) {}
VintagePort::VintagePort(const VintagePort & vp)
: Port(vp), nickname(cpNewStr(vp.nickname)), year(vp.year) {}
void VintagePort::Show() const
{
Port::Show();
cout << endl;
cout << "Nickname: " << nickname << endl;
cout << "Year: " << year << flush;
}
VintagePort & VintagePort::operator= (const VintagePort & vp)
{
if (&vp == this)
return (*this);
Port::operator=(vp);
delete[] nickname;
nickname = cpNewStr(vp.nickname);
year = vp.year;
return (*this);
}
ostream & operator<< (ostream & os, const VintagePort & vp)
{
os << Port(vp);
cout << ", " << vp.nickname << ", " << vp.year << flush;
return (os);
}
int main()
{
Port port1("gallo", "tawny", 20);
cout << port1 << endl << endl;
VintagePort vp("gallo", 24, "nice", 16);
VintagePort vp2(vp);
cout << vp2 << endl << endl;
VintagePort vp3;
vp3 = vp;
cout << vp3 << endl << endl;
Port* p_port;
p_port = &port1;
p_port->Show();
cout << endl;
p_port = &vp;
p_port->Show();
cout << endl;
}