目录
课后编程练习
习题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;
}