[42seoul] 4 circle - CPP Module 05

하이초·2023년 1월 11일
0

42seoul

목록 보기
6/11
post-thumbnail

CPP05 github 😋

1. ex00

👀 cpp05는 예외 처리에 대해 공부해보는 과제였다. 그 중 ex00은 향후 cpp05과제의 기반이 되는 관료 클래스를 만드는 과제였다. 그놈의 const가 귀찮게 하는 과제. 복사생성자랑 복사대입연산자 때문에 const 변수를 수정해야하는 경우가 생겨서,, 너무 귀찮고 힘들었다..

🥨 const_cast<new_type>(expression)

  • c++ 타입 캐스팅 중 1가지인 const_cast. 이 캐스팅 연산자를 사용하면 포인터 또는 참조형의 const 속성을 잠시 제거하고 해당 대상을 변경할 수 있다.
  • 함수 포인터에는 사용이 불가능하다고 한다
  • *(const_cast<std::string*>(&_name)) = obj.getName();과 같은 형태로 사용해서 const변수의 값을 변경할 수 있다.
  • 아주 예전에 한 번 작성했던 적이 있는 것 같긴 하지만 아무튼 const 변수는 객체 생성 시 초기화리스트를 사용하여 초기화해주어야 한다. 당연함!

🥨 std::exception

  • std::exception은 표준 예외 클래스로 예외 처리에 해당 클래스를 상속받아 커스텀 에러를 만들 수 있다.
대표적인 표준 예외 클래스
- bad_alloc: 메모리 할당 오류, new 연산에서 발생
- bad_cast: 형변환 오류로 dynamic_cast에서 발생
- bad_type_id: typeid에 대한 피 연산자가 널 포인터인 경우 발생
- bad_exception: 예기치 못한 예외로서 함수 발생 목록에 있지 않는 예외
- bad_login_error: 클래스 논리 오류
- invalid_argument, length_error, out_of_range
- runtime_error: 실행 오류
  • const char *를 반환하는 what 함수를 가지고 있다. 이를 오버라이딩하여 커스텀 에러에 알맞은 에러 메시지를 뱉도록 할 수 있다.
  • try-catch문을 사용하여 던져진 예외를 잡을 수 있으며, e.what()을 통해 설정한 메시지를 출력하려면 catch문에서 에러 객체를 참조형으로 받아야 한다. 임시 객체로 만들어질 때 아마도 what값은 복사를 안해오나보다. 참조형으로 하지 않으면 std::exception과 같은 메시지가 출력되었다.

🥨 throw

  • 함수 원형에 throw()를 붙이면 예외가 없다는 뜻이다. 이는 뭐 지난한 역사가 있었던 것 같지만, 다 생략하고 결국 C++11에는 throw()와 noexcept만 남아있고, throw() 대신 noexcept를 사용하는 것이 일반적이라고 한다.
  • 던져진 예외는 꼭 catch로 잡아줘야 한다. 잡히지 않은 에러가 가장 상단까지 올라가다보면,, 생각하고 싶지 않은 결과를 만들어낼 수 있다..ㅎ

2. ex01

👀 ex01은 관료가 사용할 form을 만들어보는 과제였다. 관료의 등급과 연계하여 해당 form은 sign과 execute에 적정 조건이 붙게 된다. 이 과제야말로 정말로 귀찮은 과제였다. const의 향연,, 고만해,,,

🥨 const 복사대입연산자

  • const 변수가 많아서 여기서도 계속 const_cast를 사용해야 했다.. 구찮

🥨 beSigned, signForm

  • 해당 함수들은 적절하게 만들면 된다. 안 어려움. 그저 노가다.

3. ex02

👀 ex02는 ex01에서 만든 form을 abstract 클래스로 만든 후 이를 상속하는 3가지 form을 만들어보는 과제였다.

🥨 부모의 private변수 접근하기

  • Aform 클래스의 경우 멤버변수를 protected가 아닌 private에 넣어놓다보니 자식 클래스에서 이를 직접 접근하는 것이 불가능하다.
  • 이를 해결하는 방법은 2가지 정도가 있는데, 첫째는 생성자를 활용하는 것이고 두번째는 setter 함수를 활용하는 것이다.
  • 프로젝트를 할 당시에는 대체로 setter보다는 생성자를 활용하는 방식을 많이 썼다. 이번에도 역시 그렇게 해결!
  • 부모의 복사생성자를 활용하면 되어서 자식클래스의 복사생성자는 좀 꿀이었다 히힛.
  • 다만 대입연산자는 부모의 대입연산자를 활용하되 반환되는 것이 부모클래스 포인터기 때문에 dynamic_cast를 활용하여 다운캐스팅을 해주었다.

🥨 아스키트리
- 인터넷에 떠도는 아스키트리 중 맘에 드는 것을 복붙했다.
- '\' 기호를 활용하여 string이 계속 이어지도록 했음.

🥨 랜덤

  • 걍 srand함수로 때렸다..

4. ex03

👀 ex03은 폼을 자동으로 만들어주는,, 그런 인턴클래스를 만드는 과제여따.. 참나 사람을 시다바리로 봐도 유분수가 있지.. 아주~! 별 걸 다 시켜!

🥨 함수 포인터 배열 활용

  • 그치만 사실 별로 할 건 없음
  • 사실 처음에는 switch-case 문을 활용했었는데 좀 더 깔끔한 방법이 없을까!!! 함수포인터를 활용할 방법이 정녕없는가!!! 를 고민하다가 드디어 해결했다.
  • 처음 고민했던 것은 함수포인터 사용 시 AForm 클래스에 해당 활용 함수들을 만들어야 할 것 같았고, 그러려면 또 AForm클래스에 3가지 폼클래스를 다 인클루드 해줘야한다고 생각해서 멈칫했었다.
  • 그런데 그러나 그럴 필요가 없었다. 걍 각 3가지 폼클래스에 스태틱 함수를 만들어주면 되는거였다! 아니 사실 내가 함수 포인터를 잘 몰라서 고민했던 것 같기도 하다.
  • ❓ 사실 아직 잘 모르겠는 건 스태틱으로 만들지 않으면 다른 클래스 함수의 경우 아직 클래스가 생성되지 않았기 때문에 해당 함수를 주소로서 활용하여 함수포인터 배열에 넣을 수 없는가? 이다. 테스트해보면 되지만 귀찮아서 테스트는 포기.. 근데 아마 안될 것 같다. 아니다 되려나.. 하지만 생성되지 않은 클래스에 대해 함수를 사용한다는 건 어불성설 아닌가? 스태틱 함수를 활용하는 게 맞는 것 같다 🤔

🚴 CPP 가보자고!

profile
개발국대가 되는 그 날까지. 지금은 개발 응애.

0개의 댓글