42seoul/projects

[CPP Module] 05

moaoh 2024. 3. 13. 15:12

๋ฐ˜๋ณต๊ณผ ์˜ˆ์™ธ์ฒ˜๋ฆฌ (Repetition and Exceptions)

https://jun-13.tistory.com/144

 

[C++] Repetition and Exceptions

Repetition and Exceptions๋ž€? ์˜ˆ์™ธ ํด๋ž˜์Šค ํด๋ž˜์Šค์•ˆ์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ํ™•์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ํŽธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ํด๋ž˜์Šค class Bureaucrat { public: class GradeTooHighException : public std::exception { public: const char *wha

moaoh.dev


Ex00: Mommy, when I grow up, I want to be a bureaucrat!

์˜ˆ์™ธ์ฒ˜๋ฆฌ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๊ฐœ๋…์— ๋Œ€ํ•ด ๊ธฐ์ดˆ์ ์œผ๋กœ ๊ณต๋ถ€ํ•˜๋Š” ํŒŒํŠธ

bureaucrat ํด๋ž˜์Šค

const std::string	name;	// ์ด๋ฆ„
int   ****grade; // ๋“ฑ๊ธ‰

ํ•ด๋‹น ํด๋ž˜์Šค์—๊ฒŒ grade๋ฅผ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๊ณ  grade์˜ ๋ฒ”์œ„๋Š” 1 ~ 150 ( ์ˆซ์ž๊ฐ€ ์ž‘์„์ˆ˜๋ก ๋†’์Œ ) ํ˜•์‹์œผ๋กœ ์ด๋ฃจ์–ด ์ง„๋‹ค.

ํ•ด๋‹น ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” grade๊ฐ€ ๋“ค์–ด์˜ค๊ฒŒ๋˜๋ฉด exception ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๋ฐ˜๋ก€๋ฅผ ์žก์•„๋‚ธ๋‹ค.

const char* Bureaucrat::GradeTooLowException::what() const throw()
{
	return ("Grade too low");
}
.
.
.

int	main() {
	try {
		Bureaucrat	a("a", 150);
		Bureaucrat	b("b", 1);

		a.upGrade();
		b.downGrade();
		std::cout << a << std::endl;
		std::cout << b << std::endl;

		b.setGrade(0);

		a.downGrade();
		a.downGrade();
	}
	catch (std::exception &e) {
		std::cout << "error : " << e.what() << std::endl;
	}
}

์œ„์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์ง„ํ–‰์ด ๋œ๋‹ค.

const ๋ฉค๋ฒ„ ๋ณ€์ˆ˜

ํ•ด๋‹น class์—์„œ๋Š” name๊ฐ’์„ constํ˜•์‹์œผ๋กœ ๊ตฌํ˜„์„ ํ•ด์•ผํ•œ๋‹ค๊ณ  ๋ช…์‹œ๋ฅผ ํ•˜๊ณ ์žˆ๋‹ค.

class Bureaucrat
{
private:
	const std::string	name;
	...
public:
	...
};

๊ทธ๋ž˜์„œ ์œ„์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ const name์œผ๋กœ ๋“ค์–ด์˜จ ๊ฐ’์„ ์ง€์ •ํ•ด์ค˜์•ผํ•˜๋Š”๋ฐ

์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ์–ด๋–ป๊ฒŒ ๊ฐ’์„ ๋Œ€์ž…์‹œ์ผœ์•ผํ•˜๋Š”์ง€๊ฐ€ ๊ณ ๋ฏผ์ด์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ทธ๊ฒƒ์— ํ•ด๋‹นํ•˜๋Š” ๋‚ด์šฉ์„ ์ฐพ์•„๋ณด๋‹ˆ const ๋ฉค๋ฒ„๋ณ€์ˆ˜๋ผ๋Š” ๋‚ด์šฉ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๊ณ ,

Bureaucrat::Bureaucrat(const std::string str, int _grade) : name(str)

์œ„์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์ƒ์„ฑ์ž์—์„œ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ๊ฐ’์„ ๋Œ€์ž…ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐ’์„ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.


Ex01: Form up, maggots

try - catch์˜ ์‘์šฉ์„ ํ•ด๋ณด๋Š” ํŒŒํŠธ

Form ํด๋ž˜์Šค

const std::string	name;	// ์ด๋ฆ„
bool							isSign; // sign์ด ๋˜์—ˆ๋Š”์ง€ ์•ˆ๋˜์–ด์žˆ๋Š”์ง€ ํ™•์ธ 
const int					signGrade; // sign์ด ๊ฐ€๋Šฅํ•œ grade์ธ์ง€ ํ™•์ธ
const int					executeGrade; // form ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ grade์ธ์ง€ ํ™•์ธ

beSigned( const Bureaucrat& bure )

void		Bureaucrat::signForm( Form& form )

์‹ค์งˆ์ ์œผ๋กœ sign์ด ์ด๋ฃจ์–ด ์ง€๋Š” ํŒŒํŠธ

์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” bureaucrat์˜ grade์— ๋”ฐ๋ผ์„œ form์˜ grade์™€ ๋น„๊ตํ•˜์—ฌ ์‹ธ์ธ์ด ๊ฐ€๋Šฅํ•œ grade์ธ์ง€ ํŒ๋ณ„์„ ํ•œ๋‹ค.

signForm( Form& form )

void	Form::beSigned( const Bureaucrat& bure )

besigned๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ cout๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ํŒŒํŠธ

signForm์—์„œ beSigned๋ฅผ ์‹คํ–‰ํ•˜์—ฌ sign์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๊ทธ๋Œ€๋กœ ๊ทธ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” output ์ถœ๋ ฅ.

sign์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด try - catch๋กœ ๊ฐ’์„ ์žก์•„์„œ error ์ถœ๋ ฅ.

๋‚ด์šฉ์ •๋ฆฌ

Bureaucrat์™€ form์€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๊ณ 

Bureaucrat์˜ grade์™€ form์˜ grade์™€ ๋น„๊ตํ•˜์—ฌ sign์ด ๊ฐ€๋Šฅํ•œ์ง€, form์„ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š”์ง€ ์—†๋Š”์ง€๋ฅผ ๋น„๊ตํ•˜๋ฉฐ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚จ๋‹ค.

ex00์—์„œ๋Š” mainํŒŒํŠธ์—์„œ๋งŒ try - catchํ˜•์‹์„ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ ex01์—์„œ๋Š” singform์ด๋ผ๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ try - catch ํ˜•์‹์„ ์‚ฌ์šฉํ•ด๋ณด์•˜๋‹ค.

error๊ฐ€ catch๋ฌธ์—์„œ ์žกํžˆ๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์‹คํ–‰์„ ์ข…๋ฃŒํ•˜๊ธฐ๋•Œ๋ฌธ์— main์ด ์•„๋‹Œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ catch๋ฅผ ํ•˜๋ฉด main์€ ์ด์–ด์„œ ๊ณ„์† ์‹คํ–‰์ด ๋œ๋‹ค.


Exercise 02: No, you need form 28B, not 28C...

try - catch๋ฅผ ๋”์šฑ ๋” ์‘์šฉํ•ด๋ณด๋Š” ํŒŒํŠธ

ํ•ด๋‹น ํŒŒํŠธ์—์„œ๋Š” ์ „์— ๋งŒ๋“ค์—ˆ๋˜ Formํด๋ž˜์Šค๋ฅผ AFormํ˜•์‹์œผ๋กœ ๋ฐ”๊พธ๊ณ  AForm์„ ์ƒ์†๋ฐ›๋Š” 3๊ฐœ์˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

PresidentialPardonForm

RobotomyRequestForm

ShrubberyCreationForm

AForm์„ ์ƒ์†๋ฐ›๋Š” 3๊ฐœ์˜ ํด๋ž˜์Šค์—์„œ๋„ AForm์˜ ๋ฉค๋ฒ„๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ถ”๊ฐ€์ ์œผ๋กœ target์ด๋ผ๊ณ ํ•˜๋Š” string๊ฐ’์„ ๋” ๋ฐ›์•„์ค˜์•ผํ–ˆ๊ธฐ๋•Œ๋ฌธ์—

// AForm.hpp
class AForm
{
private:
	const std::string	name;
	const std::string	target;
	bool							isSign;
	const int					signGrade;
	const int					executeGrade;
.
.
.
}

// PresidentialPardonForm.cpp
PresidentialPardonForm::PresidentialPardonForm(
	std::string _name, std::string _target) :
	AForm(_name, _target, 145, 137) {}

์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ _name๊ณผ _target์„ ์ถ”๊ฐ€๋กœ ๋” ๋ฐ›์•„์„œ subject์—์„œ ์š”๊ตฌํ•˜๋Š” ์‚ฌํ•ญ์„ ํ• ๋‹นํ•ด์ฃผ์—ˆ๋‹ค.


Exercise 03: At least this beats

coffee-making

Intern someRandomIntern;
AForm* rrf;
rrf = someRandomIntern.makeForm("robotomy request", "Bender");
rrf = someRandomIntern.makeForm("error form", "Bender");

Intern์ด๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ์œ„์™€ ๊ฐ™์€ ์ผ€์ด์Šค๋กœ makeForm์— formName์— ๋งž๋Š” form๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ’์„ ์ „๋‹ฌ์„ ํ•ด์ค˜์•ผํ•œ๋‹ค.

๋งŒ์•ฝ makeform์— formName ์— ๋งค์นญ์ด๋˜๋Š” ๊ฐ’์ด ์—†๋‹ค๋ฉด throw๋กœ error๊ฐ’์„ ๋˜์ ธ์•ผํ•œ๋‹ค.

You must avoid unreadable and ugly solutions like using a if/elseif/else forest.

ํ•ด๋‹น ๋ฌธ์ œ์—์„œ ์กฐ๊ฑด์— ์œ„์™€๊ฐ™์€ ๋ฌธ๊ตฌ๊ฐ€ ์จ์ ธ์žˆ์–ด์„œ ํ•ด๋‹น๋ถ€๋ถ„์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผํ• ๊นŒ ๊ณ ๋ฏผ์„ ํ•˜๋‹ค๊ฐ€

forest๋ผ๋Š” ๋ฌธ๊ตฌ์— ์ง‘์ค‘์„ ํ•˜์—ฌ if๋ฌธ์„ ํ•˜๋‚˜๋งŒ ์“ฐ๋Š” ๋ฐฉ์‹์œผ๋กœ ํƒ€ํ˜‘์„ ๋ณด๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

์ •์  ๋ฉค๋ฒ„๋ž€

class MyClass {
public:
    static void staticFunction() {
        std::cout << "This is a static member function." << std::endl;
    }
};

int main() {
    MyClass::staticFunction(); // ์ •์  ๋ฉค๋ฒ„ ํ•จ์ˆ˜ ํ˜ธ์ถœ

    return 0;
}

์œ„์™€ ๊ฐ™์ด static void * ํ˜•์‹์œผ๋กœ ์„ ์–ธ๋œ ํ•จ์ˆ˜๋ฅผ ์ •์  ๋ฉค๋ฒ„ํ˜•์‹์œผ๋กœ ์„ ์–ธ์ด ๋˜์–ด์žˆ๋‹ค๊ณ  ์ด์•ผ๊ธฐํ•œ๋‹ค (static์˜ ์œ ๋ฌด)

class MyClass {
public:
    void memberFunction() {
        std::cout << "This is a member function." << std::endl;
    }

    static void staticFunction() {
        std::cout << "This is a static member function." << std::endl;
    }
};

int main() {
    MyClass myObject;
    myObject.memberFunction(); // ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉ

    MyClass::staticFunction(); // ์ •์  ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ
}

์œ„์— ์˜ˆ์ œ์—์„œ ์ •์ ๋ฉค๋ฒ„๋กœ ์„ ์–ธ๋œ๊ฒฝ์šฐ์™€ ๊ทธ๋ƒฅ ๋ฉค๋ฒ„๋กœ ์„ ์–ธ์ด ๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ๋น„๊ตํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์ •์  ๋ฉค๋ฒ„์— ๊ฒฝ์šฐ์—๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

AForm *(*forms[3])(std::string const &target) = {
		&ShrubberyCreationForm::create,
		&RobotomyRequestForm::create,
		&PresidentialPardonForm::create
};

๊ทธ๋ž˜์„œ ์œ„์™€๊ฐ™์€ ํ˜•์‹์œผ๋กœ forms๋ผ๋Š” ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด AForm์„ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋“ค์˜ ์ •์ ๋ฉค๋ฒ„ ํ•จ์ˆ˜์€ createํ•จ์ˆ˜๋“ค์„ ๋‹ด์•„

if (formName == formNames[i]) {
			std::cout << "Intern creates " << formName << std::endl;
			return forms[i](target);
}

์œ„์™€๊ฐ™์€ ์กฐ๊ฑด๋ฌธ ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.