c++ Primer Plus(习题13.1)
/*13.1题的实现文件,书上的测试文件*/
//哪个方法不需要也根据实现而定,始终跟随客户的脚步
//这题细节方面被坑了,mainworks字符数组设置太小了,导致了一系列不可思议的问题
#include<iostream>
#include"classic.h"
using namespace std;
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.Roport();
c2.Roport();
cout << "Using type cd *pointer to objects:\n";
pcd->Roport();
pcd = &c2;
pcd->Roport();
cout << "Calling a funtion with a Cd reference argument:\n";
Bravo(c1); //这也是测试虚方法,由调用对象决定
Bravo(c2);
cout << "Testing assigment: \n";
Classic copy; //测试派生类的赋值运算符
copy = c2;
copy.Roport();
return 0;
}
void Bravo(const Cd&disk)
{
disk.Roport();
}
#pragma once
#pragma execution_character_set("utf-8")
//本文件为utf-8编码格式
//习题12.1的头文件
#ifndef CLASSIC_H
#define CLASSIC_H
#include<iostream>
class Cd
{
private:
char performers[50];
char label[20];
int selections;
double playtime;
public:
Cd(char *s1, char*s2, int n, double x);
Cd() {};
Cd(const Cd&d);
~Cd() {}; //由于不是动态分配内存,需不需要这个都行
virtual void Roport()const;
Cd& operator=(const Cd &d);
};
class Classic:public Cd //公有继承
{
private:
char mainworks[50]; //存储主要作品
public:
Classic(char *m, char *s1, char*s2, int n, double x);
Classic() {};
Classic(const Classic&c);
~Classic() {};
void Roport()const;
Classic&operator=(const Classic &c);
};
#endif // !CLASSIC_H
#include"classic.h"
//base calss mothod
Cd::Cd(char *s1, char*s2, int n, double x):selections(n),playtime(x)
{
std::strcpy(performers, s1); //使用初始化列表好像无法初始化performers和label
std::strcpy(label, s2);
}
//copy construction function
Cd::Cd(const Cd&d)
{
std::strcpy(performers, d.performers);
std::strcpy(label,d.label);
selections = d.selections;
playtime = d.playtime;
}
void Cd::Roport()const
{
using std::cout;
using std::endl;
cout << "Performers: " << performers << endl
<< "Lable: " << label << endl
<< "Selections: " << selections << endl
<< "Playtime: " << playtime << endl;
}
Cd& Cd::operator=(const Cd &d)
{
if (this == &d)
return *this;
std::strcpy(performers, d.performers);
std::strcpy(label, d.label);
selections = d.selections;
playtime = d.playtime;
return *this;
}
//Classic mothods
Classic::Classic(char *m, char *s1, char*s2, int n, double x):Cd(s1,s2,n,x)
{ //成员初始化;列表初始化基类数据
std::strcpy(mainworks, m);
}
void Classic::Roport()const
{
Cd::Roport(); //调用基类的report方法
std::cout << "Mainworks: " << mainworks << std::endl;
}
Classic&Classic::operator=(const Classic&c)
{
if (this == &c)
return *this;
Cd::operator=(c);
std::strcpy(mainworks, c.mainworks);
return *this;
}
Classic::Classic(const Classic&c)
{
std::strcpy(mainworks, c.mainworks);
}
c++ Primer Plus(习题13.2)
#pragma once
#pragma execution_character_set("utf-8")
//本文件为utf-8编码格式
//习题12.1的头文件
#ifndef NEWCLASSIC_H
#define NEWCLASSIC_H
#include<iostream>
class Cd
{
private:
char *performers;
char *label;
int selections;
double playtime;
public:
Cd(char *s1, char*s2, int n , double x);
//Cd(const Cd&d);
Cd() {};
virtual ~Cd() { delete[]performers; delete[] label; }; //由于不是动态分配内存,需不需要这个都行
virtual void Roport()const;
Cd& operator=(const Cd &d);
};
class Classic :public Cd //公有继承
{
private:
char *mainworks; //存储主要作品
public:
Classic(char *m,char *s1, char*s2, int n, double x);
Classic() {};
virtual ~Classic() { delete[]mainworks; };
void Roport()const;
Classic&operator=(const Classic &c);
};
#endif // !CLASSIC_H
#include"newclassic.h"
//base calss mothod
Cd::Cd(char *s1, char*s2, int n, double x) :selections(n), playtime(x)
{
performers = new char[std::strlen(s1)+1];
label = new char[std::strlen(s2)+1];
std::strcpy(performers, s1); //使用初始化列表好像无法初始化performers和label
std::strcpy(label, s2);
}
void Cd::Roport()const
{
using std::cout;
using std::endl;
cout << "Performers: " << performers << endl
<< "Lable: " << label << endl
<< "Selections: " << selections << endl
<< "Playtime: " << playtime << endl;
}
Cd& Cd::operator=(const Cd &d)
{
if (this == &d)
return *this;
//这里不加delete[]perfomers是因为构造函数没用new[]初始化
performers = new char[std::strlen(d.performers) + 1];
label = new char[std::strlen(d.label) + 1];
std::strcpy(performers, d.performers);
std::strcpy(label, d.label);
selections = d.selections;
playtime = d.playtime;
return *this;
}
//Classic mothods
Classic::Classic(char *m, char *s1, char*s2, int n, double x) :Cd(s1, s2, n, x)
{ //成员初始化;列表初始化基类数据
mainworks = new char[std::strlen(m)+1];
std::strcpy(mainworks, m);
}
void Classic::Roport()const
{
Cd::Roport(); //调用基类的report方法
std::cout << "Mainworks: " << mainworks << std::endl;
}
Classic&Classic::operator=(const Classic&c)
{
if (this == &c)
return *this;
Cd::operator=(c);
//这里也不用delete[]mainworks;
mainworks = new char[std::strlen(c.mainworks) + 1];
std::strcpy(mainworks, c.mainworks);
return *this;
}
/*13.2题的实现文件,书上的测试文件*/
//和上一题一模一样的实现文件,就是把字符数组改成动态内存分配
//老套路,可删除的函数有复制构造函数,因为没用到,这么简单的题玩了一下午
#include<iostream>
#include"newclassic.h"
using namespace std;
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.Roport();
c2.Roport();
cout << "Using type cd *pointer to objects:\n";
pcd->Roport();
pcd = &c2;
pcd->Roport();
cout << "Calling a funtion with a Cd reference argument:\n";
Bravo(c1); //这也是测试虚方法,由调用对象决定
Bravo(c2);
cout << "Testing assigment: \n";
Classic copy; //测试派生类的赋值运算符和默认构造函数
copy = c2;
copy.Roport();
return 0;
}
void Bravo(const Cd&disk)
{
disk.Roport();
}
c++ Primer Plus(习题13.3)
//变更书上三种DMA的关系,使他们从一个抽象基类中派生出来
//这是根据书上程序清单13.10模仿出来的测试文件
//头文件省略了很多方法,可以说是一个专门解决特定客户需求的类
#include<iostream>
#include"dma.h"
const int CLENTS = 3;
int main()
{
using namespace std;
Abc *p[CLENTS];
char temp[30];
int temrating;
char choose;
for (int i = 0; i < CLENTS; i++)
{
cout << "Enter the label: ";
cin.getline(temp, 30);
cout << "Enter the rating: ";
cin >> temrating;
cout << "Enter 1 for baseDMA class or "
"2 for lacksDMA class or 3 for hasDMA class: ";
while (cin >> choose && (choose != '1'&&choose!='2'&&choose!='3'))
cout << "Make you choice rightly!";
if (choose == '1')
p[i] = new baseDMA(temp, temrating);
else if (choose == '2')
{
char temc[10];
cin.get(); //混合输入数字和字符串切记处理换行符
cout << "Enter the color: ";
cin.get(temc, 10);
p[i] = new lacksDMA(temc, temp, temrating);
}
else
{
char temstyle[10];
cout << "Enter the style: ";
cin.get();
cin.get(temstyle, 10);
p[i] = new hasDMA(temstyle, temp, temrating);
}
while (cin.get() != '\n')
continue;
}
cout << endl;
for (int i = 0; i < CLENTS; i++)
{
p[i]->Report();
cout << endl;
}
for (int i = 0; i < CLENTS; i++)
{
delete p[i]; //free emory!
}
cout << "*************Test complete!**************\n";
return 0;
}
#pragma once
#pragma execution_character_set("utf-8")
//本文件为utf-8编码格式
//使用抽象基类abc派生出三个类
#ifndef DMA_H
#define DMA_H
#include<iostream>
class Abc
{
private:
char *label;
int rating;
protected:
char* Label()const { return label; } //保护方法,报告抽象基类中的成员
int Rating()const { return rating; }
public:
Abc(const char *l = "NULL", int r = 0);
virtual void Report()const = 0; //纯虚函数的标志,基类可以不提供定义
virtual ~Abc() { delete[]label; }
};
class baseDMA:public Abc
{
public:
baseDMA(const char *l = "NULL", int r = 0) :Abc(l, r) {};
virtual ~baseDMA() {};
virtual void Report()const;
};
class lacksDMA:public Abc
{
private:
enum{COL_LEN=40};
char color[COL_LEN];
public:
lacksDMA(const char *la = "NULL", const char*l = "NULL", int r = 0);
virtual ~lacksDMA() {};
virtual void Report()const;
};
class hasDMA :public Abc
{
private:
char *style;
public:
hasDMA(const char*s = "NULL", const char*l = "NULL", int r = 0);
virtual ~hasDMA() { delete[]style; };
virtual void Report()const;
};
#endif // !DMA_H
#include"dma.h"
using std::cout;
using std::endl;
//Abc mothod
Abc::Abc(const char *l, int r)
{
label = new char[std::strlen(l) + 1];
std::strcpy(label, l);
rating = r;
}
//baseDMA METHOD
void baseDMA::Report()const
{
cout << "Label: " << Label() << endl //调用抽象基类的保护方法
<< "Rating: " << Rating() << endl;
}
//lacksDMA method
lacksDMA::lacksDMA(const char *la, const char*l, int r) :Abc(l, r)
{
std::strcpy(color, la);
}
void lacksDMA::Report()const
{
cout << "Label: " << Label() << endl
<< "Rating: " << Rating() << endl
<< "Color: " << color << endl;
}
//hasDMA method
hasDMA::hasDMA(const char*s, const char*l, int r) :
Abc(l, r)
{
style = new char[std::strlen(s) + 1];
std::strcpy(style, s);
}
void hasDMA::Report()const
{
cout << "Label: " << Label() << endl
<< "Rating: " << Rating() << endl
<< "Style: " << style << endl;
}
c++ Primer Plus(习题13.4)
//一题填空题,得自己编写文件测试全部方法
//b:有的方法需要重新定义,比如说析构函数还有构造函数,等等,都是必须重新定义的
//c:重载的赋值运算符和输出符基类的引用完全够用,不用声明成虚的方法
#include<iostream>
#include"port.h"
int main()
{
using std::cout;
using std::endl;
Port a("Hong", "tawny", 100);
VintagePort b("La", 20, "The Noble", 2017);
cout << "Resource A: " << a << "\nResource B: " << b << endl;
cout << "Test copy construction c=a: \n";
Port c=a;
c.Show();
cout << "Test << operator:\n";
cout << c;
cout << "\nTest a+=15 and b-=15:";
a += 15;
b -= 15;
cout << " A: " << a << " B: " << b << endl;
cout << "Test virtual method:\n ";
Port *p = &a;
p->Show();
p = &b;
p->Show();
cout << "c=b ";
c = b;
c.Show();
cout << "\n*************Test complete!**************\n";
return 0;
}
#pragma once
#pragma execution_character_set("utf-8")
//本文件为utf-8编码格式
#ifndef PORT_H
#define PORT_H
#include<iostream>
using namespace std;
class Port
{
private:
char *brand;
char style[20]; //ie.,tawny,ruby,vintage
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); // add b to bottles
Port&operator-=(int b);
virtual void Show()const;
friend ostream& operator<<(ostream&os, const Port&p);
protected:
int BottleCount()const { return bottles; }
};
class VintagePort :public Port
{
private:
char *nickname;
int year;
public:
VintagePort();
VintagePort(const char*nn, int y, const char*br, int b);
VintagePort(const VintagePort &vp);
~VintagePort() { delete[]nickname; };
VintagePort&operator=(const VintagePort&vp);
virtual void Show()const;
friend ostream&operator<<(ostream&os, const VintagePort&pt);
};
#endif // !PORT_H
#include"port.h"
using std::cout;
using std::endl;
//Port methods
Port::Port(const char*br, const char *st, int b)
{
brand = new char[std::strlen(br) + 1];
std::strcpy(brand, br);
std::strcpy(style, st);
bottles = b;
}
Port::Port(const Port&p)
{
brand = new char[std::strlen(p.brand) + 1];
std::strcpy(brand, p.brand);
std::strcpy(style, p.style);
bottles = p.bottles;
}
Port&Port::operator=(const Port&p)
{
if (this == &p)
return *this;
delete[]brand;
brand = new char[std::strlen(p.brand) + 1];
std::strcpy(brand, p.brand);
std::strcpy(style, p.style);
bottles = p.bottles;
return *this;
}
Port&Port::operator+=(int b)
{
bottles += b;
return *this;
}
Port&Port::operator-=(int b)
{
bottles -= b;
return *this;
}
//out put methods
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 methods
VintagePort::VintagePort()
{
nickname = new char[1];
nickname = nullptr;
year = 0;
}
VintagePort::VintagePort(const char*br,int b, const char*nn, int y):Port(br,"vintage",b)
{
nickname = new char[std::strlen(nn) + 1];
std::strcpy(nickname, nn);
year = y;
}
VintagePort::VintagePort(const VintagePort &vp):Port(vp)
{
delete[]nickname;
nickname = new char[std::strlen(vp.nickname) + 1];
std::strcpy(nickname, vp.nickname);
year = vp.year;
}
VintagePort&VintagePort::operator=(const VintagePort&vp)
{
if (this == &vp)
return *this;
delete[]nickname;
nickname = new char[std::strlen(vp.nickname) + 1];
std::strcpy(nickname, vp.nickname);
year = vp.year;
return *this;
}
void VintagePort::Show()const
{
Port::Show(); //调用基类的方法,用来显示基类部分
cout << "Nick name: " << nickname << endl
<< "Year: " << year << endl;
}
ostream&operator<<(ostream&os, const VintagePort&pt)
{
os << (const Port&)pt;
os << " , " << pt.nickname << " , ";
return os;
}