Exercise 00
exception class는 Orthodox Canonical Foam이 지켜지지 않아도 됩니다.
주어진 등급 외의 사용하여 인스턴스화하려는 것에 대해서 예외 처리를 해야 합니다.
- Bureaucrat::GradeTooHighException
- Bureaucrat::GradeTooLowException
필수적인 요소
- constant name
- grade
- getters
- getName
- getGrade
- member function
- increment grade
- decrement grade
- overload of the insertion («) operator to print
갑작스러운 const에 대한 공부
const
constant의 약자로 상수를 의미합니다
const 사용
- const 변수
: 할당 시 초기화되지 않은 상태로 둘 수 없습니다
const std::string objectName = "chair";
std::string const objectName = "chair"; // 위와 동일한 의미
// const std::string name; 잘못된 접근
// name = "table" 잘못된 접근
- When the pointer variable point to a const value
: 포인터 변수가 가리키는 값에 대하여 상수화
const data_type* var_name;
/* example */
int x(10);
char y('M');
const int* i = &x;
const char* j = &y;
x = 9;
y = 'A';
/*
// Compile Error : read-only variable is not assignable
// *i = 3;
// *j = 'C';
*/
- When the const pointer variable point to the value
: 포인터 변수 자체를 상수화
data_type* const var_name;
/* example */
int x(7);
int y(42);
int* const i = &x;
// i = &y; Error
x = 8;
- 위에서 언급된 두 개 모두 const
int num = 1;
const int* const ptr = #
// 참조자는 애초에 참조하는 대상을 변경할 수 없는 특징이 있기 때문에 아래와 같이 사용
const int& ref = num;
- const member function
: 맴버 함수 내의 모든 맴버 변수를 상수화
Const 멤버 변수를 복사 생성자에?
복상 생성자에서 해당 값을 들고와서 입력을 받기 위해서 Constructor member initializer list(생성자 멤버 초기화 리스트)를 사용하면 입력할 수 있습니다. 코드로 설명을 하자면,
// 불가능
Bureaucrat::Bureaucrat(const Bureaucrat& origin)
{
this->name = oringin.getName();
this->grade = origin.getGrade();
}
// 가능
Bureaucrat::Bureaucrat(const Bureaucrat& origin) : name(origin.getName())
{
this->grade = origin.getGrade();
}
try throw catch
명령문을 사용하면 실행 되는 try동안 오류를 테스트할 코드 블록을 정의할 수 있습니다.
문제가 감지되면 키워드에서 throw 예외 (참고) 발생하여 사용자 지정 오류를 생성할 수 있습니다.
이 catch명령문을 사용하면 try 블록에서 오류가 발생할 경우 실행할 코드 블록을 정의할 수 있습니다.
try 및 키워드 는 catch쌍으로 제공
try {
// Block of code to try
throw exception; // Throw an exception when a problem arise
}
catch () {
// Block of code to handle errors
}
std::execption
오동작을 방지하는 프로그램을 설계할 수 있도록 언어 차원에서 자원
std::exception::what (참고)
// C++ 98
virtual const char* what() const throw();
// example
#include <exception>
#include <iostream>
struct ooops : std::exception {
const char* what() const throw() { return "Ooops!\n"; }
};
int main() {
try {
throw ooops();
} catch (std::exception& ex) {
std::cout << ex.what();
}
return 0;
}
c++ 11 사용되는 specifier
override : In a member function declaration or definition, override specifier ensures that the function is virtual and is overriding a virtual function from a base class
explicit : it cannot be used for implicit conversions and copy-initialization
delete : To disable the usage of a member function. This is done by appending the '=delete;'
default : Explicitly defaulted function declaration is a new form of function declaration that is introduced standard which allows you to append the '=default;'
개체 출력자 (참고)
기본 형식의 값을 ostream 형식 개체와 왼쪽 쉬프트(<<) 연산자를 이용하여 스트림에 출력할 때와 같이 사용자가 정의한 형식도 기본 형식처럼 ostream 형식 개체를 이용하여 출력하는 하는 것
// *.hpp
ostream &operator<<(ostream &os,const Bureaucrat &bureaucrat);
// *.cpp
ostream &operator<<(ostream &os,const Bureaucrat &bureaucrat)
{
// os << 출력하고자 하는 문구
return os;
}
Exercise 01
Foam 클래스를 만듭니다.
attributes are private
- const name
- bool signed(default false)
- const grade to sign
- const grade to execute
등급에 대한 것은 Bureaucrat(ex00 참조)에 따릅니다.
ex00와 동일하게 예외 처리가 필요합니다 (Form::GradeTooHighException, Form::GradeTooLowException)
이전과 마찬가지로 모든 속성에 대해 getter를 작성하고 모든 양식의 정보를 인쇄하는 객체 출력자를 만들면 됩니다.
Bureaucrat을 참조하는 beSigned() member function
Add a signForm() member function to the Bureaucrat. 아래와 같이 출력되어야 합니다.
: <bureaucrat> signed <form> 그렇지 않다면 <bureaucrat> couldn’t sign <form> because <reason>
Exercise 02
기본 클래스 양식은 추상 클래스여야 합니다
속성은 비공개로 유지되어야 하며 기본 클래스에 있어야 합니다.
concrete classes를 추가 합니다.
- ShrubberyCreationForm : Required grades: sign 145, exec 137
작업 디렉터리에 파일 <target>_shrubbery를 만들고 그 안에 ASCII 트리를 작성합니다. - RobotomyRequestForm: Required grades: sign 72, exec 45
구멍 뚫는 소리를 냅니다.
이후, <target>이 50% 로봇화에 성공했음을 알립니다. 그렇지 않은 경우 로봇 검사가 실패했음을 알립니다. - PresidentialPardonForm: Required grades: sign 25, exec 5
<target>이 사면되었음을 알립니다.
이들 모두 생성자에서 하나의 매개 변수, 즉 양식의 대상만 사용합니다. 예를 들어, 여러분이 집에 관목을 심고 싶다면 "집"이라고 합니다.
이제 기본 폼에 const execute(Bureaucrat const & executor) 멤버 함수를 추가하고 Form의 concrete classes동작을 실행하는 함수를 구현
서명이 되어 있는지, 서식을 실행하려는 관료들의 등급이 충분히 높은지 확인해야 합니다. 그렇지 않으면 적절한 예외를 적용합니다.
concrete class : new 키워드를 사용하여 인스턴스를 만드는 클래스, 구상 클래스
모든 구상 클래스에서 또는 기본 클래스에서 요구 사항을 확인할 것을 권유합니다.
executeForm(Form const & form) 멤버 함수를 the Bureaucrat 에 만듭니다.
성공적인 경우 다음을 인쇄하십시오.
<bureaucrat> executed <form>
그렇지 않으면 명시적 오류 메시지를 인쇄 해야 합니다.
50% 라는 확률을 사용하기 위해 랜덤함수를 사용
std::rand() (참고)
: Pseudo-random integral value between 0 and RAND_MAX.
사용을 위해서 % 연산자를 통해서 값을 제한하고 그 범위 내에서 어떻게 사용할지 정하면 됩니다.
#include <cstdlib>
#include <iostream>
// 0 ~ 99 까지의 숫자가 나옵니다.
int pers = std::rand() % 100;
if (pers < 50)
std::cout << "under 50" << std::endl;
else
std::cout << "it's big number. Just joke!!" << std::endl;
기본 폼에 const execute(Bureaucrat const & executor) 멤버 함수를 추가하지만 상속받는 자식 클래스에서만 사용이 되기에
순수 가상 함수를 사용해야 합니다. 즉 Form은 abstract class(추상 클래스)가 됩니다.
CPP05부터는 통과를 하기 위해서 Exercise03까지 진행을 해야합니다. 어떻게 알았냐구요? ... 알고 싶지 않았습니다
Exercise03
Intern 이라는 클래스를 만들고, 내부 멤버 함수 Form* makeForm(name of form, target of form) 를 만드세요.
if/elseif/else 문을 사용하지 마세요.
예외 처리를 해야 합니다.
if/elseif/else를 사용하지 않고 해당 값을 찾는 방법에는 멤버 함수 포인터(CPP01 ex05 참조)를 사용하면 됩니다.
참고1, 참고2 참고하여서 간략한 예시를 들면,
// 사용된 find는 algorithm.h에 속해있습니다.
Animal *ret = NULL;
Animal *(*func[5])(std::string name) = {makeCat, makeDog, ...}
std::string types[] = {"cat", "dog", ...}
std::string *pick = std::find(types, types + types.size(), type);
if (pick == types + types.size()) {
std::cerr << "Wrong complain! Try again!" << std::endl;
} else {
ret = (func[pick - tpyes])(std::string name);
}
return ret;
'42 Seoul' 카테고리의 다른 글
[42Seoul] CPP07 template (0) | 2022.07.25 |
---|---|
[42Seoul] CPP06 type_casting (0) | 2022.07.23 |
[CPP 03~05] class, inheritance memory address (0) | 2022.07.21 |
[42Seoul] CPP04 virtual (0) | 2022.07.15 |
[42Seoul] CPP 03 클래스 상속 (0) | 2022.07.15 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!