CPP Module 01

hhkim·2022년 5월 15일
0

42cursus

목록 보기
10/20
post-thumbnail

ex00 - BraiiiiiiinnnzzzZ

개념

클래스의 정적 할당

스택 영역에 할당됨

  • 함수가 끝날 때 자동으로 소멸
  • . 연산자로 인스턴스에 접근
Test t("hello");
t.display();

클래스의 동적 할당

힙 영역에 할당됨

  • new 키워드 사용
  • delete로 메모리가 반환될 때 소멸
  • -> 연산자로 인스턴스에 접근
Test *t = new Test("hello");
t->display();
delete t;
t = 0;

구현

  • 좀비를 스택에 할당할 것인지 힙에 할당할 것인지 결정
  • 더이상 사용되지 않으면 소멸자를 통해 삭제해야 함

Zombie 클래스

  • 멤버 변수: private name
  • 멤버 함수: 좀비 자기소개
void announce( void );
<name>: BraiiiiiiinnnzzzZ...
  • 소멸자: 디버깅을 위해 좀비 이름과 함께 메시지 출력

함수 구현

  • 좀비 생성, 이름 붙이기, 밖에서도 사용할 수 있도록 포인터 리턴 (newZombie.cpp)
  • 밖에서도 사용할 수 있어야 하니까 힙에 할당
 Zombie* newZombie( std::string name );
  • 좀비 생성, 이름 붙이기, 좀비 자기소개 (randomChump.cpp)
  • 함수 내부에서만 사용하고 말 거니까 스택에 할당
 void randomChump( std::string name );

ex01 - Moar brainz!

개념

객체 배열

  • new []delete []
Test *test_arr = new Test[10];
delete [] test_arr;
test_arr = 0;

구현

  • 한번에 N 마리의 좀비를 생성하는 함수
  • 모든 좀비는 name으로 이름 설정
  • 첫 번째 좀비의 포인터 리턴
Zombie* zombieHorde( int N, std::string name );
  • 각 좀비의 announce를 호출하는 테스트 작성
  • delete로 모든 좀비의 메모리 해제

👉 일단 객체 배열을 생성한 다음 반복문을 돌면서 각 인스턴스의 이름 설정해주기 (setter 구현)


ex02 - HI THIS IS BRAIN

개념

https://gracefulprograming.tistory.com/11

int a = 10;
int *p = &a;  // 포인터
int &r = a;  // 참조자

포인터(pointer)

변수의 메모리 주소를 가지는 변수
(C와 같은 개념)

참조자(reference)

변수의 다른 이름 (별명)

  • 선언과 동시에 초기화해야 함
  • 한 번 초기화하면 재할당할 수 없음
  • 함수에 매개변수로 전달하면 * 연산자를 따로 사용할 필요없이 원본 변수를 변경할 수 있어서 코드가 간결해짐
  • C++에서는 가능하면 포인터보다 참조자를 사용하도록 권하고 있음
    (포인터를 잘못 사용해서 발생하는 오류를 최소화하기 위함)

구현

  • HI THIS IS BRAIN로 초기화된 string 변수 생성
  • stringPTR: string을 가리키는 포인터
  • stringREF: string의 참조자
  • 아래 내용 출력
  1. string 변수의 주소
  2. stringPTR가 가진 주소
  3. stringREF가 가진 주소
  4. string 변수의 값
  5. stringPTR가 가리키는 값
  6. stringREF가 가리키는 값

ex03 - Unnecessary violence

개념

const 참조자

참조하는 값이 const가 아니라도 const로 간주하도록 하는 참조자

  • 참조자를 통해 변경 불가능하니까 안전
  • r-value 값이 참조자의 수명에 맞게 확장됨
int x = 5;
const int &ref1 = x;  // non-const 참조

const int y = 7;
const int &ref2 = y;  // const 참조

const int &ref3 = 6;  // r-value 참조

l-value, r-value

  • l-value: 메모리 주소를 가지는 값
  • r-value: 메모리 주소가 없고, 표현식 범위에만 있는 임시 값 (지역 변수, 대입연산자 오른쪽에 있는 값)

구현

Weapon 클래스

  • private 멤버 변수 std::string type
  • 멤버 함수
    • getType(): type의 const 참조자 리턴
    • setType(): 인자로 받은 값을 type으로 세팅

HumanA, HumanB 클래스

  • 멤버 변수: Weapon, name
  • 멤버 함수 attack()
    • 아래 내용 출력
<name> attacks with their <weapon type>
  • HumanA는 생성자에서 Weapon을 얻지만 HumanB는 아님
  • HumanB가 항상 Weapon을 가지고 있지는 않지만 HumanA는 항상 가지고 있음

👉 HumanA는 생성자에서 Weapon을 얻기 때문에 Weapon을 참조자로 가지고, HumanB는 그렇지 않으므로 포인터로 가지도록 구현

테스트 코드

  • 각 테스트케이스 모두 crude spiked club, some other type of club 순으로 2번 메시지 출력
int main()
{
    {
      Weapon club = Weapon("crude spiked club");
      
      HumanA bob("Bob", club);
      bob.attack();
      club.setType("some other type of club");
      bob.attack();
    }
    {
      Weapon club = Weapon("crude spiked club");
      
      HumanB jim("Jim");
      jim.setWeapon(club);
      jim.attack();
      club.setType("some other type of club");
      jim.attack();
    }
    
	return 0;
}

ex04 - Sed is for losers

개념

fstream

파일 입출력 스트림

문자열 치환

구현

  • 인자 3개(filename, s1, s2)를 받는 프로그램
  • filename 파일을 열어서 filename.replace에 복사하는데, s1s2로 바꿈
  • C의 파일 관련 함수를 사용할 수 없음
  • std::string::replace()를 사용할 수 없음
  • 잘못된 입력에 대한 에러를 처리해야 함
  • 적절한 테스트 코드 작성하기

ex05 - Harl 2.0

개념

함수 포인터

함수를 가리키는 포인터

리턴타입 (*변수명)(매개변수리스트);

int foo(int x) { return x; }

int (*ptr)(int) = foo;

멤버 함수 포인터

https://beafreespirit.tistory.com/85

  • 클래스명을 명시하고, 클래스의 주소를 & 연산자로 가져와야 함
  • 클래스를 인스턴스화 시킨 후 그 인스턴스를 통해 함수 포인터를 사용해야 함 (.*, ->* 연산자 사용)
리턴타입 (클래스명::*변수명)(매개변수 리스트);

class Test
{
public:
	int foo(int x) { return x; }
};

Test test;
int (Test::*ptr)(int) = &Test::foo;
std::cout << (test.*ptr)(1) << std::endl;
  • 클래스의 멤버 함수 내부에서 함수 포인터를 사용한다면 this(해당 멤버 함수를 호출한 객체의 주소)를 통해 호출 가능
    (인스턴스가 생성되지 않아서 아직 함수가 메모리에 할당되지 않았으므로)
리턴타입 (클래스명::*변수명)(매개변수 리스트);

class Test
{
private:
	int foo(int x) { return x; }
public:
	void goo(int x) {
    	int (Test::*ptr)(int) = &Test::foo;
        std::cout << (this->*f)(x) << std::endl;
    }
};

구현

로그 남기기

  • DEBUG: 맥락 정보. 프로그램 진단에 사용됨
    예) "I love having extra bacon for my 7XL-double-cheese-triple-pickle-specialketchup burger. I really do!"
  • INFO: 추가 정보. 프로그램 실행이나 환경을 남길 때 유용
    예) "I cannot believe adding extra bacon costs more money. You didn’t put enough bacon in my burger! If you did, I wouldn’t be asking for more!"
  • WARNING: 시스템의 잠재적인 문제. 핸들링 가능하거나 무시될 수 있음
    예) "I think I deserve to have some extra bacon for free. I’ve been coming for years whereas you started working here since last month."
  • ERROR: 복구 불가능한 에러 발생. 직접 간섭이 필요한 치명적인 문제
    예) "This is unacceptable! I want to speak to the manager now."

Harl 클래스

  • private 멤버 함수
void debug( void );
void info( void );
void warning( void );
void error( void );
  • public 멤버 함수: 입력받은 레벨에 따른 private 멤버 함수 호출
void complain( std::string level );
  • 멤버 함수에 대한 포인터 사용
    함수 포인터를 배열로도 선언 가능
  	void (*f_ptr[4])(void) = {&Harl::debug, &Harl::info, &Harl::warning, &Harl::error};
  • if/else if/else 구문을 사용하지 말 것
  • 테스트 코드를 함께 제출
  • 메시지는 자유롭게 써도 되고, 예시를 그대로 써도 됨

ex06 - Harl filter

구현

  • 4가지 로그 레벨 중 하나를 파라미터로 받는 프로그램 harlFilter
  • 해당 레벨 이상의 모든 메시지 출력
  • switch 구문 사용
  • 유효하지 않은 레벨이 입력되면 [ Probably complaining about insignificant problems ] 출력
$> ./harlFilter "WARNING"
[ WARNING ]
I think I deserve to have some extra bacon for free.
I've been coming for years whereas you started working here since last month.

[ ERROR ]
This is unacceptable, I want to speak to the manager now.

$> ./harlFilter "I am not sure how tired I am today..."
[ Probably complaining about insignificant problems ]

0개의 댓글