有很多细节需要回味!
//baseclass.h
#pragma once
class Cd {
private:
char* performers;
char* label;
int selections;
double playtime;
public:
Cd(const char* s1, const char* s2, int n, double x);
Cd(const Cd& d); //copy constructor
Cd(); //default constructor
virtual ~Cd(); //destructor
virtual void Report() const;
virtual Cd& operator=(const Cd& d);
};
class Classic :public Cd {
private:
char* works;
public:
Classic();
Classic(const char* s1, const char* s2,const char* s3, int n, double x);
~Classic();
Classic(const Classic& c);
virtual void Report() const;
virtual Classic& operator=(const Classic& d);
};
//baseclass.cpp
#include<iostream>
#include"baseclass.h"
using namespace std;
Cd::Cd(const char* s1, const char* s2, int n, double x) {
delete[] performers;
delete[] label;
performers = new char[strlen(s1) + 1];
strcpy_s(performers, strlen(s1) + 1, s1);
label = new char[strlen(s2) + 1];
strcpy_s(label, strlen(s2) + 1, s2);
selections = n;
playtime = x;
}
//copy constructor
Cd::Cd(const Cd& d) {
delete[] performers;
delete[] label;
performers = new char[strlen(d.performers) + 1];
strcpy_s(performers, strlen(d.performers) + 1, d.performers);
label = new char[strlen(d.label) + 1];
strcpy_s(label, strlen(d.label) + 1, d.label);
playtime = d.playtime;
selections = d.selections;
}
//default constructor
Cd::Cd() {
performers = new char[1];
performers[0] = '/0';
label = new char[1];
label[0] = '/0';
playtime = 0.0;
selections = 0;
}
//destructor
Cd::~Cd() {
delete[] performers;
delete[] label;
}
void Cd::Report() const {
cout << "Performers: " << performers << endl;
cout << "Label: " << label << endl;
cout << "Number of selection: " << selections << endl;
cout << "Playtime: " << playtime << endl;
cout << endl;
}
Cd& Cd::operator=(const Cd& d) {
if (this == &d) {
return *this;
}
delete[] performers;
delete[] label;
performers = new char[strlen(d.performers) + 1];
strcpy_s(performers, strlen(d.performers) + 1, d.performers);
label = new char[strlen(d.label) + 1];
strcpy_s(label, strlen(d.label) + 1, d.label);
playtime = d.playtime;
selections = d.selections;
return *this;
}
Classic::Classic() : Cd() {
works = new char[1];
works[0] = '/0';
}
Classic::~Classic() {
delete[] works;
}
Classic::Classic(const char* s1, const char* s2, const char* s3, int n, double x) : Cd(s1, s2, n, x) {
delete[] works;
works = new char[strlen(s3) + 1];
strcpy_s(works, strlen(s3) + 1, s3);
}
Classic::Classic(const Classic& c) :Cd(c) { //调用基类的拷贝构造初始化基类成员
delete[] works;
works = new char[strlen(c.works) + 1];
strcpy_s(works, strlen(c.works) + 1, c.works);
}
void Classic::Report() const {
//强制转换为基类对象,以输出基类的成员数据
//Cd d(*this); //利用Cd的构造函数:Cd指针或引用指向Classic对象
//d.Report();
Cd::Report(); //可以直接调用基类的Report
cout << "Main works: " << works << endl;
cout << endl;
}
Classic& Classic::operator=(const Classic& d) {
if (this == &d) return *this;
//调用基类的赋值运算符给派生类中基类成员赋值
Cd::operator=(d); //调用基类赋值运算符
delete[] works;
works = new char[strlen(d.works) + 1];
strcpy_s(works, strlen(d.works) + 1, d.works);
return *this;
}
//main.cpp
#include<iostream>
#include"baseclass.h"
using namespace std;
void Bravo(const Cd& disk);
int main() {
Cd c1("Beatles", "Captiol", 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();
c2.Report();
cout << "Using type cd* pointer to objects: \n";
pcd->Report();
pcd = &c2;
pcd->Report();
cout << "Calling a function with a Cd reference argument:\n";
Bravo(c1);
cout << endl;
Bravo(c2);
cout << "Tesing assignment: \n";
Classic copy;
copy = c2;
copy.Report();
return 0;
}
void Bravo(const Cd& disk) {
disk.Report();
}