본문 바로가기
개인공부/C++ 기초플러스

C++ Primer 13 Exercise

by 하고싶은건많은놈 2023. 2. 19.

01

// classic.h

#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();
		virtual void Report() const;
};

class Classic : public Cd
{
	private:
		char represent[30];
	public:
		Classic(char * s1, char * s2, char * s3, int n, double x);
		Classic();
		void Report() const;
};

#endif
// classic.cpp

#include "CLASSIC.h"
#include <cstring>

Cd::Cd(char * s1, char * s2, int n, double x)
{
	strcpy(performers, s1);
	strcpy(label, s2);
	selections = n;
	playtime = x;
}

Cd::Cd()
{
}

void Cd::Report() const
{
	using std::cout;
	using std::endl;

	cout << "----------------------------\n";
	cout << "performer : " << performers << endl;
	cout << "label : " << label << endl;
	cout << "selections : " << selections << endl;
	cout << "playtime : " << playtime << endl;
}
 
 Classic::Classic(char * s1, char * s2, char * s3, int n, double x) 
	: Cd(s1, s2, n, x)
 {
	strcpy(represent, s3);
 }

 Classic::Classic()
 {
 }

void Classic::Report() const
{
	using std::cout;
	using std::endl;

	Cd::Report();
	cout << "represent : " << represent << endl;
}
// pe13-01.cpp

#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 << "객체를 직접 사용한다 : \n";
	c1.Report();
	c2.Report();

	cout << "객체를 지시하는 Cd * 포인터를 사용한다 : \n";
	pcd->Report();
	pcd = &c2;
	pcd->Report();

	cout << "Cd 참조 매개변수를 사용하여 함수를 호출한다 : \n";
	Bravo(c1);
	Bravo(c2);

	cout << "대입을 테스트한다 : \n";
	Classic copy;
	copy = c2;
	copy.Report();

	return 0;
}

void Bravo(const Cd & disk)
{
	disk.Report();
}

02

// classic1.h

#ifndef CLASSIC1_H_
#define CLASSIC1_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();
		~Cd();
		virtual void Report() const;
		Cd & operator=(const Cd & d);
};

class Classic : public Cd
{
	private:
		char * represent;
	public:
		Classic(char * s1, char * s2, char * s3, int n, double x);
		Classic();
		~Classic();
		void Report() const;
		Classic & operator=(const Classic & d);
};

#endif
// classic1.cpp

#include "CLASSIC1.h"
#include <cstring>

Cd::Cd(char * s1, char * s2, int n, double x)
{
	performers = new char[strlen(s1) + 1];
	strcpy(performers, s1);
	label = new char[strlen(s2) + 1];
	strcpy(label, s2);
	selections = n;
	playtime = x;
}

Cd::Cd()
{
}

Cd::~Cd()
{
	delete [] performers;
	delete [] label;
}

void Cd::Report() const
{
	using std::cout;
	using std::endl;

	cout << "----------------------------\n";
	cout << "performer : " << performers << endl;
	cout << "label : " << label << endl;
	cout << "selections : " << selections << endl;
	cout << "playtime : " << playtime << endl;
}

Cd & Cd::operator=(const Cd & d)
{
	delete [] performers;
	performers = new char[strlen(d.performers) + 1];
	strcpy(performers, d.performers);
	
	delete [] label;
	label = new char[strlen(d.performers) + 1];
	strcpy(label, d.label);

	selections = d.selections;
	playtime = d.playtime;

	return *this;
}
 
Classic::Classic(char * s1, char * s2, char * s3, int n, double x) 
	: Cd(s1, s2, n, x)
 {
	represent = new char[strlen(s3) + 1];
	strcpy(represent, s3);
 }

Classic::Classic()
 {
 }

Classic::~Classic()
{
	delete [] represent;
}

void Classic::Report() const
{
	using std::cout;
	using std::endl;

	Cd::Report();
	cout << "represent : " << represent << endl;
}

Classic & Classic::operator=(const Classic & d)
{
	Cd::operator=(d);
	delete [] represent;
	represent = new char[strlen(d.represent) + 1];
	strcpy(represent, d.represent);
	return *this;
}
// pe13-02.cpp

#include <iostream>
using namespace std;
#include "CLASSIC1.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 << "객체를 직접 사용한다 : \n";
	c1.Report();
	c2.Report();

	cout << "객체를 지시하는 Cd * 포인터를 사용한다 : \n";
	pcd->Report();
	pcd = &c2;
	pcd->Report();

	cout << "Cd 참조 매개변수를 사용하여 함수를 호출한다 : \n";
	Bravo(c1);
	Bravo(c2);

	cout << "대입을 테스트한다 : \n";
	Classic copy;
	copy = c2;
	copy.Report();

	return 0;
}

void Bravo(const Cd & disk)
{
	disk.Report();
}

03

// dmaabc.h

#ifndef DMAABC_H_
#define DMAABC_H_
#include <iostream>

class AbcDMA
{
	private:
		char * label;
		int rating;
	public:
		AbcDMA(const char * l = "null", int r = 0);
		AbcDMA(const AbcDMA & rs);
		virtual ~AbcDMA();
		virtual void View() const = 0;
		const char* showLabel() const { return label; } 
		int showRating() const { return rating; }
		AbcDMA & operator=(const AbcDMA & rs);
		friend std::ostream & operator<<(std::ostream & os, const AbcDMA & rs);
};

class baseDMA : public AbcDMA
{
	private:
	public:
		baseDMA(const char * l, int r);
		baseDMA(const baseDMA & rs);
		virtual ~baseDMA();
		baseDMA & operator=(const baseDMA & rs);
		friend std::ostream & operator<<(std::ostream & os, const baseDMA & rs);
		virtual void View() const;
};

class lacksDMA : public AbcDMA
{
	private:
		enum { COL_LEN = 40 };
		char color[COL_LEN];
	public:
		lacksDMA(const char * c = "blank", const char * l = "null", int r = 0);
		friend std::ostream & operator<<(std::ostream & os, const lacksDMA & rs);
		virtual void View() const;
};

class hasDMA : public AbcDMA
{
	private:
		char * style;
	public:
		hasDMA(const char * s = "none", const char * l = "null", int r = 0);
		hasDMA(const hasDMA & hs);
		~hasDMA();
		hasDMA & operator=(const hasDMA & rs);
		friend std::ostream & operator<<(std::ostream & os, const hasDMA & rs);
		virtual void View() const;
};

#endif
// dmaabc.cpp

#include "DMAABC.h"
#include <cstring>

AbcDMA::AbcDMA(const char * l, int r)
{
	label = new char[std::strlen(l) + 1];
	std::strcpy(label, l);
	rating = r;
}

AbcDMA::AbcDMA(const AbcDMA & rs)
{
	label = new char[std::strlen(rs.label) + 1];
	std::strcpy(label, rs.label);
	rating = rs.rating;
}

AbcDMA::~AbcDMA()
{
	delete [] label;
}

void AbcDMA::View() const
{
	std::cout << "상표 : " << label << std::endl;
	std::cout << "등급 : " << rating << std::endl;
}

AbcDMA & AbcDMA::operator=(const AbcDMA & rs)
{
	if (this == &rs)
		return *this;

	delete [] label;
	label = new char[std::strlen(rs.label) + 1];
	std::strcpy(label, rs.label);
	rating = rs.rating;
	return *this;
}

std::ostream & operator<<(std::ostream & os, const AbcDMA & rs)
{
	os << "상표 : " << rs.label << std::endl;
	os << "등급 : " << rs.rating << std::endl;
	return os;
}

baseDMA::baseDMA(const char * l, int r)
	: AbcDMA(l, r)
{
}

baseDMA::baseDMA(const baseDMA & rs)
	: AbcDMA(rs)
{
}

baseDMA::~baseDMA()
{
}

baseDMA & baseDMA::operator=(const baseDMA & rs)
{
	AbcDMA::operator=(rs);
	return *this;
}

std::ostream & operator<<(std::ostream & os, const baseDMA & rs)
{
	os << (const AbcDMA &)rs;
	return os;
}

void baseDMA::View() const
{
	std::cout << "baseDMA\n";
	std::cout << "상표 : " << showLabel() << std::endl;
	std::cout << "등급 : " << showRating() << std::endl;
}

lacksDMA::lacksDMA(const char * c, const char * l, int r) : AbcDMA(l, r)
{
	std::strncpy(color, c, 39);
	color[39] = '\0';
}

std::ostream & operator<<(std::ostream & os, const lacksDMA & ls)
{
	os << (const AbcDMA &)ls;
	os << "색상 : " << ls.color << std::endl;
	return os;
}

void lacksDMA::View() const
{
	std::cout << "lacksDMA\n";
	std::cout << "상표 : " << showLabel() << std::endl;
	std::cout << "등급 : " << showRating() << std::endl;
	std::cout << "색상 : " << color << std::endl;
}

hasDMA::hasDMA(const char * s, const char * l, int r) : AbcDMA(l, r)
{
	style = new char[std::strlen(s) + 1];
	std::strcpy(style, s);
}

hasDMA::hasDMA(const hasDMA & hs) : AbcDMA(hs)
{
	style = new char[std::strlen(hs.style) + 1];
	std::strcpy(style, hs.style);
}

hasDMA::~hasDMA()
{
	delete [] style;
}

hasDMA & hasDMA::operator=(const hasDMA & hs)
{
	if (this == &hs)
		return *this;

	AbcDMA::operator=(hs);
	delete [] style;
	style = new char[std::strlen(hs.style) + 1];
	std::strcpy(style, hs.style);
	return *this;
}

std::ostream & operator<<(std::ostream & os, const hasDMA & hs)
{
	os << (const AbcDMA &) hs;
	os << "스타일 : " << hs.style << std::endl;
	return os;
}

void hasDMA::View() const
{
	std::cout << "hasDMA\n";
	std::cout << "상표 : " << showLabel() << std::endl;
	std::cout << "등급 : " << showRating() << std::endl;
	std::cout << "스타일 : " << style << std::endl;
}
// pe13-03.cpp

#include <iostream>
#include "DMAABC.h"

int main()
{
	using std::cout;
	using std::cin;
	using std::endl;

	int num;
	AbcDMA *dma;
	AbcDMA *temp[3];

	temp[0] = new baseDMA("bbbb", 1);
	temp[1] = new lacksDMA("black", "llll", 2);
	temp[2] = new hasDMA("warm", "hhhh", 3);

	cout << "base=1, lacks=2, has=3\n";
	cout << "번호를 선택해주십시오 : ";
	if (cin >> num)
	{
		switch(num)
		{
			case 1:
				dma = new baseDMA("base", 1111);
				dma->View();
				cout << endl;
				dma = temp[0];
				cout << *dma;
				break;
			case 2:
				dma = new lacksDMA("white", "lacks", 2222);
				dma->View();
				cout << endl;
				dma = temp[1];
				cout << (const lacksDMA &)*dma;
				break;
			case 3:
				dma = new hasDMA("cool", "has", 3333);
				dma->View();
				cout << endl;
				dma = temp[2];
				cout << (const hasDMA &)*dma;
				break;
		}
	}
	else
		cout << "잘못 입력하였습니다. 프로그램을 종료합니다.\n";
	
	return 0;
}

04

// port.h

#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

a)

// port.cpp

#include "port.h"
#include <cstring>

Port::Port(const char * br, const char * st, int b)
{
	brand = new char[strlen(br) + 1];
	strcpy(brand, br);
	strcpy(style, st);
	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)
{
	delete [] brand;
	brand = new char[strlen(p.brand) + 1];
	strcpy(brand, p.brand);
	strcpy(style, p.style);
	bottles = p.bottles;
}

Port & Port::operator+=(int b)
{
	bottles += b;
}

Port & Port::operator-=(int b)
{
	bottles -= b;
}

void Port::Show() const
{
	cout << "브랜드 : " << brand << endl;
	cout << "스타일 : " << style << endl;
	cout << "수량 : " << bottles << endl;
}

ostream & operator<<(ostream & os, const Port & p)
{
	os << p.brand << ", " << p.style << ", " << p.bottles;
}

b) operator=(), Show(), operator<< 함수의 경우 VintagePort 클래스에서 새롭게 선언된 멤버들까지 조작해야하므로 새롭게 재정의됨
나머지 함수의 경우 Port 클래스에서나 VintagePort 클래스에서나 동작이 같기 때문에 재정의할 필요가 없음

c) 함수의 시그내처가 다르기 때문에 해당 클래스의 함수가 사용되기 때문

d)

// vintageport.cpp

#include "port.h"
#include <cstring>

VintagePort::VintagePort()
{
}

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();
	cout << "별명 : " << nickname << endl;
	cout << "년도 : " << year << endl;
}

ostream & operator<<(ostream & os, const VintagePort & vp)
{
	os << (const Port &)vp;
	os << ", " << vp.nickname << ", " << vp.year << endl;
}

'개인공부 > C++ 기초플러스' 카테고리의 다른 글

C++ Primer 14 Exercise  (0) 2023.02.21
C++ Primer 14  (0) 2023.02.21
C++ Primer 13  (0) 2023.02.19
C++ Primer 12 Exercise  (0) 2023.02.19
C++ Primer 12  (0) 2023.02.19

댓글