cpp05

YP J·2022년 6월 25일
0

CppModule

목록 보기
6/9

ex00

Mommy, when I grow up, I want to be a bureaucrat!
Turn-in directory : ex00/
Files to turn in : Makefile, main.cpp, Bureaucrat.{h, hpp}, Bureaucrat.cpp
Forbidden functions : None
{
/* do some stuff with bureaucrats */
}
catch (std::exception & e)
{
/* handle exception */
}

try & catch

try

  • 예외발생에 대한 검사의 범위를 지정한다.
    'catch`
  • try블록의 바로 뒤에 등장하며, try블록에서 발생한 예외를 처리하는 코드가 담기는 영역이다.
  • 형태반환형 없는 함수와 유사하다.
  • 하나의 try블록에서 다수의 catch 블록이 존재할 수있다. ( 데이터의 자료형이 상황에 따라 다를수 있기 때문)

throw

  • 예외가 발생했음을 알린다.
  • 예외상황에 대한 정보를 담은, 의미 있는 데이터를 catch문의 매개변수로 전달한다.
  • 어떤 함수 안에서 예외가 발생하여 throw 절이 실행됐는데 그 함수 내에 try~catch문이 존재하지 않는다면 예외처리에 대한 책임은 그 함수를 호출한 영역으로 넘어가게 된다. - (스택 풀기 의 개념)

try&catch

  • 예외가 생긴 경우 throw를 쓰고 전달하고 싶은 객체를 써준다.
  • 아무 객체나 던져도 상관 없지만 표준 라이브러리에 여러 예외가 정의되어있다.
  • throw한 위치에서 즉시 함수가 종료되고 예외처리 부분으로 점프한다.(가장 가까운 catch문으로)
  • stack에 생성했던 객체들을 모두 소멸 시켜준다.(소멸자로)

생성자에서 예외처리

  • 생성자에서 예외를 던질때는 소멸자가 호출되지 않기 때문에 catch에서 잘 해제 시켜줘야한다.

예외처리 순서

  • catch문의 경우 가장 먼저 대입될수 있는 객체를 받는다.
  • 기반클래스 객체, 파생클래스 객체 순으로 catch문 작성하게 되면 기반 클래스 포인터에 연결된 파생클래스 포인터의 경우 기반 클래스 catch문으로 들어가버리게 된다.
  • 때문에 catch문은 파생클래스, 기반 클래스 순으로 catch할 수있도록 작성하는것이 좋다.

모든예외 객체 catch

  • catch(...)를 쓰면 try안에서 발생한 모든 예외들을 받을수있다.

ex01

Form up, maggots!
Turn-in directory : ex01/
Files to turn in : Files from previous exercise + Form.{h, hpp}, Form.cpp
Forbidden functions : None
  • Form 클래스로 서명 받는 클래스 추가해주느것

ex02

Exercise : 02
No, you need form 28B, not 28C...
Turn-in directory : ex02/
Files to turn in : Files from previous exercises +
ShrubberyCreationForm.[{h, hpp},cpp], RobotomyRequestForm.[{h, hpp},cpp],
PresidentialPardonForm.[{h, hpp},cpp]
Forbidden functions : None

  • Form class 를 abstract class 로 만들고 이를 바탕으로 concreate class 를 만든다.
  • execute 관련한 exception 하난 더 만들어 줘야함.

ShrubberyCreationForm

  • 관목 생성품
  • target + shrubbery 파일을 생성하고 그 안에 ascii tree를 넣으면 됨.

RobotomyRequestForm

PresidentialPardonForm

  • Zaphod Beeblebrox에 의해 사면되는 form

ex03

At least this beats coffee-making
Turn-in directory : ex03/
Files to turn in : Files from previous exercises + Intern.{h, hpp}, Intern.cpp
Forbidden functions : None
{
	Intern someRandomIntern;
	Form* rrf;
	
    rrf = someRandomIntern.makeForm("robotomy request", "Bender");
}

  • intern class 를 만들어야함
  • form list 를 배열로 만들어 매핑해서 사용
  • formName 과 formType을 원소로 갖는 formList struct 선언하고 formList 배열 선언 후 makeForm에 사용

Form *makeForm(const std::string &formName, const std::string &target) const

  • formList 를 form종류에 맞게 초기화
{"presidential pardon", new PresidentialPardonForm(target)},
{"robotomy request", new RobotomyRequestForm(target)},
{"shrubbery creation", new ShrubberyCreationForm(target)},
{"", NULL}}
  • formList 에서 만드려는 form이 있는지 찾은후 있다면 해당 formType 리턴

C++ 전방선언 (forward declaration) & 상호참조

  • 식별자를 정의하기 전 식별자의 존재를 컴파일러에 미리 알리는 것으로 필요에 따라 함수, 변수, 클래스 등을 전방선언한다.

컴파일 시간을 단축시키며, 헤더포함 의존성을 줄여준다.

Core.hpp

class UtilClass;
 
class Core {
private:
	UtilClass *util;
};

Core.hpp

#include "UtilClass.h"
 
Core::Core() {
    util = new UtilClass;
}

사용하려는 클래스를 .hpp에서 먼저 선언하고 .cpp에서 사용하려는 객체의 .hpp를 include하는 방식입니다.

전방선언을 사용하면 .hpp에는 객체의 포인터만을 사용해 합나다.
이런 제한은 문법적으로 만들어진 것이 아니라 프로그램이 실행되는 구조에 의한 것입니다.

모든 포인터는 4byte의 메모리를 필요로하므로 우선 메모리만 확보해 두면 runtime에 생성되는 개체의 주소값을 저장할 수 있게 됩니다.

포인터가 아닌 객체의 인스턴스가 사용된다면 컴파일러는 클래스의 구조를 알아야 되므로 include된 .hpp파일이 필요하게 됩니다.

전방선언을 사용해서 얻게 되는 이점은 컴파일 시간이 단축된다는 것 입니다. 위 구조에서 전방선언이 아니라 .hpp를 include했다면 UtilityClass가 수정 될 때마다 컴파일로는. hpp를 다시 분석하게 되겠죠 만약 UtilityClass가 다른 h를 포함하고 Core클래스가 또 다른 곳에서 사용하게 된다면 의존성이 증가되어 컴파일 시간은 점점 늘어나게 됩니다.

전방선언은 A객체가 B를 사용하고 B객체가 A를 시용하는 상호참조에서도 유용하게 사용 됩니다.

그리고 API개발 등에서 불필요한 .hpp를 포함하지 않을 수 있다는 장점이 있습니다.

profile
be pro

0개의 댓글