第二题是在第一题的基础上让两个类使用动态分配内存,就是用char * 来代替char数组,故必需要重写重载几个函数,如:参数为自身类的构造函数,operator=运算符。
另外注意将基类的析构函数设为虚函数。代码如下:
classic.h
// base class
// #pragma once
#ifndef CLASSIC_H_
#define CLASSIC_H_
class Cd { // represents a CD disk
private:
char * performers;
char * label;
int selections; // number of selections
double playtime; // playing time in minutes
public:
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);
};
class Classic :public Cd
{
private:
char * songs;
public:
Classic(const char * sg = "", const char * s1 = "", const char * s2 = "", int n = 0, double x = 0.0);
Classic(const Classic & cl);
~Classic();
virtual void Report() const;
Classic & operator=(const Classic &cl);
};
#endif // !CLASSIC_H_
classic.cpp
#include "classic.h"
#include <iostream>
Cd::Cd(const char * s1, const char * s2, int n, double x)
{
performers = new char[std::strlen(s1) + 1];
std::strcpy(performers, s1);
label = new char[std::strlen(s2) + 1];
std::strcpy(label, s2);
selections = n;
playtime = x;
}
Cd::Cd(const Cd & d)
{
performers = new char[std::strlen(d.performers) + 1];
std::strcpy(performers, d.performers);
label = new char[std::strlen(d.label) + 1];
std::strcpy(label, d.label);
selections = d.selections;
playtime = d.playtime;
}
Cd::~Cd()
{
delete[] performers;
delete[] label;
}
void Cd::Report() const
{
std::cout << "Performers: " << performers << std::endl;
std::cout << "Label: " << label << std::endl;
std::cout << "Selections: " << selections << std::endl;
std::cout << "Playtime: " << playtime << std::endl;
}
Cd & Cd::operator=(const Cd & d)
{
if (this == &d)
return *this;
delete[] performers;
performers = new char[std::strlen(d.performers) + 1];
std::strcpy(performers, d.performers);
delete[] label;
label = new char[std::strlen(d.label) + 1];
std::strcpy(label, d.label);
selections = d.selections;
playtime = d.playtime;
return *this;
}
Classic::Classic(const char * sg, const char * s1, const char * s2, int n, double x) :Cd(s1, s2, n, x)
{
songs = new char[std::strlen(sg) + 1];
std::strcpy(songs, sg);
}
Classic::Classic(const Classic & cl) :Cd(cl)
{
songs = new char[std::strlen(cl.songs) + 1];
std::strcpy(songs, cl.songs);
}
Classic::~Classic()
{
delete[] songs;
}
void Classic::Report() const
{
Cd::Report();
std::cout << "Songs: " << songs << std::endl;
}
Classic & Classic::operator=(const Classic & cl)
{
if (this == &cl)
return *this;
Cd::operator=(cl);
delete[] songs;
songs = new char[std::strlen(cl.songs) + 1];
std::strcpy(songs, cl.songs);
return *this;
}
main.cpp
#include <iostream>
using namespace std;
#include "classic.h" // which will contain #include cd.h
void Bravo(const Cd & disk);
int main()
{
Cd cl("Beatles", "CapitoPV", 14, 35.5);
Classic c2 = Classic("Piano Sonata in-B flat, Fantasia in-C",
"Alfred Brendel", "Philips", 2, 57.17);
Cd *pcd = &cl;
cout << "Using obfectr directly:\n";
cl.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(cl);
Bravo(c2);
cout << "Testing assignment: ";
Classic copy;
copy = c2;
copy.Report();
cin.get();
return 0;
}
void Bravo(const Cd & disk)
{
disk.Report();
}