C++ Primer 15 프로그래밍 연습
01
// tv.h
#ifndef TV_H_
#define TV_H_
class Remote;
class Tv
{
public:
friend class Remote;
enum {Off, On};
enum {MinVal, MaxVal = 20};
enum {Antenna, Cable};
enum {TV, DVD};
enum {NORMAL, CONVERSATION};
Tv(int s = Off, int mc = 125) : state(s), volume(5),
maxchannel(mc), channel(2), mode(Cable), input(TV) {}
void onoff() { state = (state == On) ? Off : On; }
bool ison() const { return state == On; }
bool volup();
bool voldown();
void chanup();
void chandown();
void set_mode() { mode = (mode == Antenna) ? Cable : Antenna; }
void set_input() { input = (input == TV ) ? DVD : TV; }
void settings() const;
void set_mode2(Remote & r);
private:
int state;
int volume;
int maxchannel;
int channel;
int mode;
int input;
};
class Remote
{
private:
friend class Tv;
int mode;
int mode2;
public:
Remote(int m = Tv::TV, int m2 = Tv::NORMAL) : mode(m), mode2(m2) {}
bool volup(Tv & t) { return t.volup(); }
bool voldown(Tv & t) { return t.voldown(); }
void onfoff(Tv & t) { t.onoff(); }
void chanup(Tv & t) { t.chanup(); }
void chandown(Tv & t) { t.chandown(); }
void set_chan(Tv & t, int c) { t.channel = c; }
void set_mode(Tv & t) { t.set_mode(); }
void set_input(Tv & t) { t.set_input(); }
void show_mode2(Tv & t);
};
#endif
// tv.cpp
#include "tv.h"
#include <iostream>
bool Tv::volup()
{
if (volume < MaxVal)
{
volume++;
return true;
}
else
return false;
}
bool Tv::voldown()
{
if (volume > MinVal)
{
volume--;
return true;
}
else
return false;
}
void Tv::chanup()
{
if (channel < maxchannel)
channel++;
else
channel = 1;
}
void Tv::chandown()
{
if (channel > 1)
channel--;
else
channel = maxchannel;
}
void Tv::settings() const
{
using std::cout;
using std::endl;
cout << "TV = " << (state == Off ? "OFF" : "ON") << endl;
if (state == On)
{
cout << "볼륨 = " << volume << endl;
cout << "채널 = " << channel << endl;
cout << "모드 = " << (mode == Antenna ? "지상파 방송" : "케이블 방송") << endl;
cout << "입력 = " << (input == TV ? "TV" : "DVD") << endl;
}
}
void Tv::set_mode2(Remote & r)
{
if (state == On)
{
std::cout << "리모컨 모드 변경\n";
r.mode2 = (r.mode2 == NORMAL) ? CONVERSATION : NORMAL;
}
}
void Remote::show_mode2(Tv & t)
{
std::cout << "리모컨 모드 = " << (mode2 == t.NORMAL ? "일반" : "대화") << std::endl;
}
// use_tv.cpp
#include "tv.h"
#include <iostream>
int main()
{
using std::cout;
Tv tv;
Remote remote;
tv.onoff();
tv.settings();
remote.show_mode2(tv);
tv.set_mode2(remote);
remote.show_mode2(tv);
return 0;
}
02
// exc_mean2.h
#ifndef EXC_MEAN2_H_
#define EXC_MEAN2_H_
#include <iostream>
class bad_hmean : public std::logic_error
{
private:
double v1;
double v2;
public:
bad_hmean(const char * c, double a = 0, double b = 0) : logic_error(c), v1(a), v2(b) {}
void mesg();
};
inline void bad_hmean::mesg()
{
std::cout << "hmean(" << v1 << ", " << v2 << ") : "
<< "잘못된 매개변수 : a = -b\n";
}
class bad_gmean : public std::logic_error
{
public:
double v1;
double v2;
bad_gmean(const char * c, double a = 0, double b = 0) : logic_error(c), v1(a), v2(b) {}
const char * mesg();
};
inline const char * bad_gmean::mesg()
{
return "gmean() 매개변수들은 >= 0 이어야 합니다.\n";
}
#endif
// error5.cpp
#include "exc_mean.h"
#include <iostream>
#include <cmath>
#include <stdexcept>
double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
using std::cout;
using std::cin;
using std::endl;
double x, y, z;
cout << "두 수를 입력하십시오 : ";
while (std::cin >> x >> y)
{
try {
z = hmean(x, y);
cout << x << ", " << y << "의 조화평균은 "
<< z << "입니다.\n";
cout << x << ", " << y << "의 기하평균은 "
<< gmean(x,y) << "입니다.\n";
cout << "다른 두 수를 입력하십시오 (끝내려면 q) : ";
}
catch (bad_hmean & bg)
{
cout << bg.what() << endl;
bg.mesg();
cout << "다시 하십시오.\n";
continue;
}
catch (bad_gmean & hg)
{
cout << hg.what() << endl;
cout << hg.mesg();
cout << "사용된 값 : " << hg.v1 << ", "
<< hg.v2 << endl;
cout << "죄송합니다. 더 이상 진행할 수 없습니다.\n";
break;
}
}
cout << "프로그램을 종료합니다.\n";
return 0;
}
double hmean(double a, double b)
{
if (a == -b)
throw bad_hmean("hmean 에러!!!!!", a, b);
return 2.0 * a * b / (a + b);
}
double gmean(double a, double b)
{
if (a < 0 || b < 0)
throw bad_gmean("gmean 에러!!!!!", a, b);
return std::sqrt(a * b);
}
03
// exc_mean3.h
#ifndef EXC_MEAN2_H_
#define EXC_MEAN2_H_
#include <iostream>
class bad_: public std::logic_error
{
private:
double v1;
double v2;
public:
bad_(const char * c, double a, double b) : logic_error(c), v1(a), v2(b) {}
void show_what() { std::cout << what() << std::endl; }
double one() { return v1; }
double two() { return v2; }
virtual void mesg() = 0;
};
class bad_hmean : public bad_
{
public:
bad_hmean(const char * c, double a, double b) : bad_(c, a, b) {}
void mesg();
};
inline void bad_hmean::mesg()
{
bad_::show_what();
std::cout << "hmean(" << bad_::one() << ", " << bad_::two() << ") : "
<< "잘못된 매개변수 : a = -b\n";
}
class bad_gmean : public bad_
{
public:
bad_gmean(const char * c, double a, double b) : bad_(c, a, b) {}
void mesg();
};
inline void bad_gmean::mesg()
{
bad_::show_what();
std::cout << "gmean(" << bad_::one() << ", " << bad_::two() << ") : "
<< "잘못된 매개변수 : 매개변수들은 >= 0 이어야 합니다.\n";
}
#endif
// error6.cpp
#include "xxx.h"
#include <iostream>
#include <cmath>
#include <stdexcept>
double hmean(double a, double b);
double gmean(double a, double b);
int main()
{
using std::cout;
using std::cin;
using std::endl;
double x, y, z;
cout << "두 수를 입력하십시오 : ";
while (std::cin >> x >> y)
{
try {
z = hmean(x, y);
cout << x << ", " << y << "의 조화평균은 "
<< z << "입니다.\n";
z = gmean(x, y);
cout << x << ", " << y << "의 기하평균은 "
<< z << "입니다.\n";
cout << "다른 두 수를 입력하십시오 (끝내려면 q) : ";
}
catch (bad_ & b)
{
b.mesg();
cout << "다시 하십시오.\n";
continue;
}
}
cout << "프로그램을 종료합니다.\n";
return 0;
}
double hmean(double a, double b)
{
if (a == -b)
throw bad_hmean("hmean 에러!!!!!", a, b);
return 2.0 * a * b / (a + b);
}
double gmean(double a, double b)
{
if (a < 0 || b < 0)
throw bad_gmean("gmean 에러!!!!!", a, b);
return std::sqrt(a * b);
}
04
// use_sales2.cpp
#include "sales.h"
#include <iostream>
int main()
{
using std::cout;
using std::cin;
using std::endl;
double vals1[12] =
{
1220, 1100, 1122, 2212, 1232, 2334,
2884, 2393, 3302, 2922, 3002, 3544
};
double vals2[12] =
{
12, 11, 22, 21, 32, 34,
28, 29, 33, 29, 32, 35
};
Sales sales1(2011, vals1, 12);
LabeledSales sales2("Blogstar", 2012, vals2, 12);
cout << "첫 번째 try 블록 : \n";
try
{
int i;
cout << "Year = " << sales1.Year() << endl;
for (i = 0; i < 12; ++i)
{
cout << sales1[i] << ' ';
if (i % 6 == 5)
cout << endl;
}
cout << "Year = " << sales2.Year() << endl;
cout << "Label = " << sales2.Label() << endl;
for (i = 0; i <= 12; ++i)
{
cout << sales2[i] << ' ';
if (i % 6 == 5)
cout << endl;
}
}
catch(Sales::bad_index & bad)
{
cout << bad.what();
if (typeid(LabeledSales::nbad_index) == typeid(bad))
{
LabeledSales::nbad_index nbad = dynamic_cast<LabeledSales::nbad_index &>(bad);
cout << "Company : " << nbad.label_val() << endl;
}
cout << "잘못된 인덱스 : " << bad.bi_val() << endl;
}
cout << "\n다음 try 블록 : \n";
try
{
sales2[2] = 37.5;
sales1[20] = 23345;
cout << "try 블록 2의 끝\n";
}
catch(Sales::bad_index & bad)
{
cout << bad.what();
if (typeid(LabeledSales::nbad_index) == typeid(bad))
{
LabeledSales::nbad_index nbad = dynamic_cast<LabeledSales::nbad_index &>(bad);
cout << "Company : " << nbad.label_val() << endl;
}
cout << "잘못된 인덱스 : " << bad.bi_val() << endl;
}
cout << "프로그램을 종료합니다.\n";
return 0;
}