#pragma once #ifndef CD_H_ #define CD_H_ //base class class Cd { private: char * performers; char * label; int selection; //number of selection double playtime; public: Cd(); Cd(const Cd & d); Cd(char * s1, char * s2, int n, double x); virtual ~Cd(); virtual void Report() const; //reports all cd data Cd & operator= (const Cd & d); }; #endif // !CD_H_ #pragma once
CD.h
#pragma once #ifndef CLASSIC_H_ #define CLASSIC_H_ #include"CD.h" class Classic : public Cd { private: char * mainprod; public: Classic(); Classic(char * s1, char * s2, char * s3, int n, double x); Classic(const Classic & a); ~Classic(); Classic & operator=(const Classic & a); void Report() const; }; #endif // !CLASSIC_H_
classic.h
#include"classic.h" #include<cstring> #include<iostream> using std::strcpy; using std::strlen; using std::cout; using std::endl; //base cd Cd::Cd() { performers = new char[1]; performers[0] = ‘\0‘; label = new char[1]; label[0] = ‘\0‘; //构造函数保持统一格式对应析构函数 selection = 0; playtime = 0.0; } Cd::Cd(const Cd & a) { int len; len = strlen(a.performers); performers = new char[len + 1]; strcpy(performers, a.performers); len = strlen(a.label); label = new char[len + 1]; strcpy(label, a.label); selection = a.selection; playtime = a.playtime; } Cd & Cd::operator=(const Cd & a) { //记住第一步要先delete掉以前的,节省内存 delete[]performers; delete[]label; int len; len = strlen(a.performers); performers = new char[len + 1]; strcpy(performers, a.performers); len = strlen(a.label); label = new char[len + 1]; strcpy(label, a.label); selection = a.selection; playtime = a.playtime; return *this; } Cd::Cd(char * s1, char * s2, int n, double x) { int len; len = strlen(s1); performers = new char[len + 1]; //记得要加一,strlen不算‘\0’ strcpy(performers, s1); len = strlen(s2); label = new char[len + 1]; strcpy(label, s2); selection = n; playtime = x; } Cd::~Cd() { delete[]performers; delete[]label; } void Cd::Report() const { cout << "performers: " << performers << endl; cout << " label: " << label << endl; cout << " selection: " << selection << endl; cout << " playtime: " << playtime << endl; } Classic::~Classic() { //Cd::~Cd;//这句不用,写了报错,重复删除 delete[]mainprod;//派生析构只用删除派生类里的新成员就好 } Classic::Classic() : Cd() { mainprod = new char[1]; mainprod[0] = ‘\0‘; //构造函数要统一型式以兼容析构函数 } Classic::Classic(char * s1, char * s2, char * s3, int a, double x) : Cd(s1, s2, a, x) { int len; len = strlen(s3); mainprod = new char[len + 1]; strcpy(mainprod, s3); } Classic::Classic(const Classic & a) : Cd(a) { int len; len = strlen(a.mainprod); mainprod = new char[len + 1]; strcpy(mainprod, a.mainprod); } Classic & Classic::operator=(const Classic & a) { //先要用基类的重载= 给基类部分赋值 Cd::operator=(a); delete[]mainprod; int len; len = strlen(a.mainprod); mainprod = new char[len + 1]; strcpy(mainprod, a.mainprod); //别忘记要返回值 return *this; } void Classic::Report() const { Cd::Report(); cout << " mainproduction: " << mainprod << endl; }
method.cpp
#include<iostream> using namespace std; #include"classic.h" //will contain #include cd.h void Bravo(const Cd & disk); //记住要自己修改cd.h文件 int main() { Cd c1("Beatles", "Capitol", 14, 35.5); Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C", "Alfred Brendel", "Philios", 2, 57.17); Cd * pcd = &c1; cout << "using object directly:\n"; c1.Report(); c2.Report(); //Cd sd; cout << "using type cd * pointer to object:\n"; pcd->Report(); pcd = &c2; pcd->Report(); cout << "Calling a function with a Cd reference argument:\n"; Bravo(c1); Bravo(c2); cout << "testing assignment" << endl; Classic copy; copy = c2; copy.Report(); return 0; } void Bravo(const Cd & disk) { disk.Report(); }
test.cpp
先调用基类构造,再调用派生类构造,析构函数则相反,先调用派生类析构,再调用基类的析构函数。
派生类的析构只用删除派生里的新成员,而不用管基类部分,因为派生类析构函数会自动调用基类的析构函数,所以他自身的职责是对派生类的构造函数执行工作的清理
原文地址:https://www.cnblogs.com/syne-cllf/p/9266589.html
时间: 2024-11-08 23:31:44