第一题
classic.h
#include<iostream>
#ifndef CD_H_
#define CD_H_
class Cd
{
private:
char performers[50];
char label[20];
int selections;
double playtime;
public:
/*
* 一定要声明这种形式,因为传入实参字符串的时候
*比如"hello"这种形式为字符串常量不可修改其内容
*比较先进的编译器不声明为const的时候编译不通过
*/
Cd(const char* s1,const char* s2, int n, double x);
//不需要复制
Cd() { performers[0] = label[0] = '\0'; selections = playtime = 0.0; }
virtual ~Cd(){ }
virtual void Report()const
{
std::cout << "performers: " << performers << "\nlabel: " << label
<< "\nselections: " << selections << "\nplaytime: " << playtime;
std::cout << std::endl;
}
//不需要赋值
};
class Classic : public Cd
{
private:
char opus[50];
public:
Classic() : Cd() { opus[0] = '\0'; }
Classic(const char* opus, const char* performers, const char* label,
int selections, double playtime) : Cd(performers,label,selections,playtime)
{
strncpy(this->opus, opus,49);
this->opus[49] = '\0';
}
virtual void Report()const
{
Cd::Report();
std::cout << "opus: " << opus;
std::cout << std::endl;
}
virtual ~Classic() { } //该析构函数会自动调用基类析构
};
#endif
Cd.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"classic.h"
Cd::Cd(const char* s1,const char* s2, int n, double x)
{
selections = n;
playtime = x;
strncpy(performers, s1, 49);
strncpy(label, s2, 19);
performers[49] = label[19] = '\0';
}
Cd_main.cpp
//不用对头文件定义该宏 因为头文件里面的函数定义都为内联函数,定义该宏vs不支持strncpy,strcpy函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include"classic.h"
void Bravo(const Cd& disk);
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();
cout << endl;
c2.Report();
cout << endl;
cout << "Using type cd * pointer to objects:\n";
pcd->Report();
cout << endl;
pcd = &c2;
pcd->Report();
cout << endl;
cout << "Calling a function with a Cd reference argument:\n";
Bravo(c1);
cout << endl;
Bravo(c2);
cout << endl;
cout << "Testing assignment: ";
Classic copy;
copy = c2;
copy.Report();
return 0;
}
void Bravo(const Cd& disk)
{
disk.Report();
}
输出结果
第二题
classic.h
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#ifndef CD_H_
#define CD_H_
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&);
Cd() { performers = nullptr; label = nullptr; selections = playtime = 0; }
virtual ~Cd() { delete[]performers; delete[] label; }
virtual void Report()const;
Cd& operator=(const Cd&);
};
class Classic : public Cd
{
private:
char* opus;
public:
Classic() : Cd() { opus = nullptr; }
Classic(const char* opus, const char* performers, const char* label,
int selections, double playtime) : Cd(performers, label, selections, playtime)
{
this->opus = new char[strlen(opus) + 1];
strcpy(this->opus, opus);
}
Classic(const Classic& cla) : Cd(cla)
{
opus = new char[strlen(cla.opus) + 1];
strcpy(opus, cla.opus);
}
Classic& operator=(const Classic&);
virtual void Report()const;
virtual ~Classic() { delete[]opus; }
};
#endif
classic.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"classic.h"
using std::cout;
using std::endl;
//基类
Cd::Cd(const char* s1, const char* s2, int n, double x)
{
performers = new char[strlen(s1) + 1];
label = new char[strlen(s2) + 1];
strcpy(performers, s1);
strcpy(label, s2);
selections = n;
playtime = x;
}
Cd::Cd(const Cd& cd)
{
performers = new char[strlen(cd.performers) + 1];
label = new char[strlen(cd.label) + 1];
strcpy(performers, cd.performers);
strcpy(label, cd.label);
selections = cd.selections;
playtime = cd.playtime;
}
void Cd::Report()const
{
if (performers != nullptr && label != nullptr)
{
cout << "performers: " << performers << endl << "label: " << label << endl
<< "selections: " << selections << endl << "playtime: " << playtime << endl;
}
else if (performers == nullptr)
{
cout << "performers: " << "(null)" << endl << "label: " << label << endl
<< "selections: " << selections << endl << "playtime: " << playtime << endl;
}
else
{
cout << "performers: " << performers << endl << "label: " << "(null)" << endl
<< "selections: " << selections << endl << "playtime: " << playtime << endl;
}
/*如果使用printf("str: ", performers)这种形式就不必写这些if
*str = NULL; printf("str: ", str) 输出空或者输出(null)*/
}
Cd& Cd::operator=(const Cd& cd)
{
if (this == &cd)
return *this;
delete[]performers;
delete[]label;
performers = new char[strlen(cd.performers) + 1];
label = new char[strlen(cd.label) + 1];
strcpy(performers, cd.performers);
strcpy(label, cd.label);
selections = cd.selections;
playtime = cd.playtime;
return*this;
}
//派生类
Classic& Classic::operator=(const Classic& cla)
{
if (this == &cla)
return *this;
Cd::operator=(cla);
delete[]opus;
opus = new char[strlen(cla.opus) + 1];
strcpy(opus, cla.opus);
return *this;
}
void Classic::Report()const
{
Cd::Report();
if (opus != nullptr)
cout << "opus: " << opus << endl;
else
cout << "opus: " << "null\n";
}
class_main.cpp
//不用对头文件定义该宏 因为头文件里面的函数定义都为内联函数,定义该宏vs不支持strncpy,strcpy函数
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include"classic.h"
void Bravo(const Cd& disk);
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();
cout << endl;
c2.Report();
cout << endl;
cout << "Using type cd * pointer to objects:\n";
pcd->Report();
cout << endl;
pcd = &c2;
pcd->Report();
cout << endl;
cout << "Calling a function with a Cd reference argument:\n";
Bravo(c1);
cout << endl;
Bravo(c2);
cout << endl;
cout << "Testing assignment: ";
Classic copy;
copy = c2;
copy.Report();
return 0;
}
void Bravo(const Cd& disk)
{
disk.Report();
}
输出结果
第三题
dmaABC.h
#ifndef DMA_H_
#define DMA_H_
#include<iostream>
class dmaABC
{
private:
char* label;
int rating;
public:
dmaABC(const char* l = "null", int r = 0)
{
label = new char[strlen(l) + 1];
strcpy(label, l);
rating = r;
}
dmaABC(const dmaABC& rs)
{
label = new char[strlen(rs.label) + 1];
strcpy(label, rs.label);
rating = rs.rating;
}
virtual ~dmaABC() { delete[]label; }
dmaABC& operator=(const dmaABC& rs);
virtual void View() const = 0; //实现文件里完成
};
class baseDMA : public dmaABC
{
public:
baseDMA(const char* l = "null", int r = 0) : dmaABC(l, r) { }
baseDMA(const dmaABC& rs) : dmaABC(rs) { }
virtual ~baseDMA() { } //自动调用基类
baseDMA& operator=(const baseDMA& rs) { dmaABC::operator=(rs); }
virtual void View()const { dmaABC::View(); }
};
class lacksDMA : public dmaABC
{
private:
enum { COL_LEN = 40 };
char color[COL_LEN];
public:
lacksDMA(const char* c = "blank", const char* l = "null", int r = 0) : dmaABC(l, r)
{
strncpy(color, c,COL_LEN - 1);
color[COL_LEN - 1] = '\0';
}
lacksDMA(const char* c, const dmaABC& rs) : dmaABC(rs)
{
strncpy(color, c, COL_LEN - 1);
color[COL_LEN - 1] = '\0';
}
virtual void View()const
{
dmaABC::View();
std::cout << "color: " << color << std::endl;
}
};
class hasDMA : public dmaABC
{
private:
char* style;
public:
hasDMA(const char* s = "none", const char* l = "null", int r = 0) : dmaABC(l, r)
{
style = new char[strlen(s) + 1];
strcpy(style, s);
}
hasDMA(const char* s, const dmaABC& rs) : dmaABC(rs)
{
style = new char[strlen(s) + 1];
strcpy(style, s);
}
hasDMA(const hasDMA& hs) : dmaABC(hs)
{
style = new char[strlen(hs.style) + 1];
strcpy(style, hs.style);
}
virtual ~hasDMA() { delete[]style; }
hasDMA& operator=(const hasDMA& rs);
virtual void View()const
{
dmaABC::View();
std::cout << "style: " << style << std::endl;
}
};
#endif
dmaABC.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"dmaABC.h"
using std::cout;
using std::endl;
void dmaABC::View()const
{
cout << "label: " << label << endl
<< "rating: " << rating << endl;
}
dmaABC& dmaABC::operator=(const dmaABC& rs)
{
if (this == &rs)
return *this;
delete[]label;
label = new char[strlen(rs.label) + 1];
strcpy(label, rs.label);
rating = rs.rating;
return*this;
}
hasDMA& hasDMA::operator=(const hasDMA& has)
{
if (this == &has)
return *this;
dmaABC::operator=(has);
delete[]style;
style = new char[strlen(has.style) + 1];
strcpy(style, has.style);
return *this;
}
main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"dmaABC.h"
const int SIZE(6);
int main()
{
using std::cout;
using std::endl;
using std::cin;
//dm_abc是个数组,该数组是个指针数组,该指针数组指向了dmaABC类 并没有创建dmaABC类
dmaABC* dm_abc[SIZE];
char label[40];
int rating;
char choice;
for (int i = 0; i < SIZE; i++)
{
cout << "enter label: ";
cin >> label; //注意cin特性不可输入空 换行符
cout << "enter rating: ";
cin >> rating;
cout << "1 or 2 or 3: ";//1 是baseDMA 2是lacksDMA 3是hasDMA
while (cin >> choice && choice != '1' && choice != '2' && choice != '3')
continue;
if (choice == '1')
{
dm_abc[i] = new baseDMA(label, rating);
}
else if (choice == '2')
{
char color[40];
cout << "enter color: ";
cin >> color;
dm_abc[i] = new lacksDMA(color, label, rating);
}
else if (choice == '3')
{
char style[40];
cout << "enter style: ";
cin >> style;
dm_abc[i] = new hasDMA(style, label, rating);
}
while (cin.get() != '\n')
continue;
cout << endl;
}
cout << "=======================================\n";
for (int i = 0; i < SIZE; i++)
{
dm_abc[i]->View();
cout << endl;
}
for (int i = 0; i < SIZE; i++)
delete dm_abc[i];
return 0;
}
输出结果
第四题
port.h
#define _CRT_SECURE_NO_WARNINGS
#ifndef PORT_H_
#define PORT_H_
#include<iostream>
using namespace std;
class Port
{
private:
char* brand;
char style[20];
int bottles;
public:
Port(const char* br = "none", const char* st = "none", int b = 0);
Port(const Port& p);
virtual ~Port() { delete[]brand; }
Port& operator=(const Port& p);
Port& operator+=(int b);
Port& operator-=(int b);
int BottleCount()const { return bottles; }
virtual void Show()const;
friend ostream& operator<<(ostream& os, const Port& p);
};
class VintagePort : public Port
{
private:
char* nickname;
int year;
public:
VintagePort();
VintagePort(const char* br, int b, const char* nn, int y);
VintagePort(const VintagePort& vp);
~VintagePort() { delete[]nickname; }
VintagePort& operator=(const VintagePort& vp);
void Show()const;
friend ostream& operator<<(ostream& os, const VintagePort& vp);
};
#endif
port.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"port.h"
//基类定义
Port::Port(const char* br, const char* st, int b)
{
brand = new char[strlen(br) + 1];
strcpy(brand, br);
strncpy(style, st, 19);
style[19] = '\0';
bottles = b;
}
Port::Port(const Port& p)
{
brand = new char[strlen(p.brand) + 1];
strcpy(brand, p.brand);
strcpy(style, p.style);
bottles = p.bottles;
}
Port& Port::operator=(const Port& p)
{
if (this == &p)
return *this;
delete[]brand;
brand = new char[strlen(p.brand) + 1];
strcpy(brand, p.brand);
strcpy(style, p.style);
bottles = p.bottles;
return*this;
}
Port& Port::operator+=(int b)
{
bottles += b;
return*this;
}
Port& Port::operator-=(int b)
{
if (bottles - b >= 0)
bottles -= b;
else
cout << "Not enough quantity\n";
return*this;
}
void Port::Show()const
{
cout << "Brand: " << brand << endl
<< "Kind: " << style << endl
<< "Bottles: " << bottles << endl;
}
ostream& operator<<(ostream& os, const Port& p)
{
os << p.brand << ", " << p.style << ", " << p.bottles;
return os;
}
//派生类
VintagePort::VintagePort() : Port()
{
nickname = nullptr;
year = 0;
}
VintagePort::VintagePort(const char* br, int b,
const char* nn, int y) : Port(br,"vintage", b)
{
nickname = new char[strlen(nn) + 1];
strcpy(nickname, nn);
year = y;
}
VintagePort::VintagePort(const VintagePort& vp) : Port(vp)
{
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
}
VintagePort& VintagePort::operator=(const VintagePort& vp)
{
if (this == &vp)
return *this;
Port::operator=(vp);
delete[]nickname;
nickname = new char[strlen(vp.nickname) + 1];
strcpy(nickname, vp.nickname);
year = vp.year;
return*this;
}
void VintagePort::Show()const
{
Port::Show();
if (nickname != nullptr)
cout << "nickname: " << nickname << endl
<< "year: " << year << endl;
}
ostream& operator<<(ostream& os, const VintagePort& vp)
{
cout << (const Port&)vp;
if(vp.nickname != nullptr)
cout << ", " << vp.nickname
<< ", " << vp.year;
return os;
}
main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include"port.h"
#include<iostream>
int main()
{
Port po("Gallo", "tawny", 20);
cout << "Port::operator<<():\n";
cout << po;
cout << endl << endl;
cout << "Port::Show():\n";
po.Show();
cout << "\nPort::Show():\n";
po -= 20;
po.Show();
cout << '\n';
po += 10;
po -= 20;
cout << "\nPort::Show():\n";
po.Show();
Port port(po);
cout << "\nPort Show():\n";
port.Show();
VintagePort vin_po;
cout << "\nVintagePort::Show():\n"; //注意这里显示没有错误,没有添加为nullptr的显示
vin_po.Show();
vin_po = VintagePort("Gallo", 10, "bai", 2012); //先调用复制在调用赋值\
cout << endl;
cout << "\nVintagePort::operator<<():";
cout << endl << vin_po;
VintagePort vin = vin_po;
cout << "\n\nVintagePort::Show():\n";
vin.Show();
cout << "\nVintagePort::Show():\n";
vin_po -= 10;
vin_po.Show();
VintagePort tage(vin_po);
cout << "\nVintagePort::Show():";
tage.Show();
return 0;
}
输出结果