[42Seoul] CPP Module 01 - ex01

수빈·2022년 1월 11일
0

42CPP

목록 보기
6/11
post-thumbnail

객체 배열과 객체 포인터 배열

객체를 배열 넣는 방법은 두 가지가 있는데 객체 배열객체 포인터 배열이다.

// 객제 배열 선언
Zombie Zombies[10];
// 객체 포인터 배열 선언
Zombie *Zombies = new Zombie[10];

객체 배열

객체 배열 선언 시 생성자도 호출되지만 생성자에 인자를 전달하지 못한다.
원하는 값으로 초기화가 필요하다면 초기화 과정이 따로 필요하다.
객체 배열 생성 시 생성자가 호출되는 것이 확인된다, 배열 소멸 시 소멸자도 호출.

객체 포인터 배열

객체의 주소를 담는 방식. 선언 후 일일히 동적할당하여 반환된 객체의 주소값을 배열에 대입해 줘야 함.

zombieHorde 함수

N개의 Zombie를 한 번에 할당해야 하며 한 번에 삭제되어야 한다. 주소를 반환하라고 하지 않았으니 객체 배열로 만든다.

ex00에 사용한 함수를 그대로 재활용해도 된다는 조건에 추가 작업할 시간은 줄었는데 함수를 작성하고 보니 name이 그대로 사용되어 구분이 어려웠다.

C에서 사용한 atoi처럼 c++에도 방법이 있을 것이라 판단해 찾아 보았다 itos라는 함수가 있었는데 해당 함수는 버전이 높아 지금 상황에서는 쓸 수 없었다. 직접 만들거나 다른 방법을 찾아야 했는데 블로그를 발견해 해당 방법을 찾았다

Zombie* zombieHorde( int N, std::string name )
{
	Zombie	*numzom = new Zombie[N];
	std::stringstream	ss;

	for (int i = 0; i < N; i++)
	{
		ss << i;
		numzom[i].setName(name + ss.str());
		numzom[i].announce();
		ss.str("");
	}
	return (numzom);
}

방법은 간단하다. i로 들어온 int 값을 ss에 넣고, 해당 값을 str()형식으로 출력해 setName으로 name을 변경한다.

기본 생성자를 통해 인스턴스를 만들기 위해 기본 생성자를 명시했다.

zombieHorde에서 값을 초기화하지 않고 계속 값을 추가했더니 이렇게 됐다. 함수 사용에는 문제가 없지만 보기에 좋지 않아서 사용이 끝나면 초기화하는 방식으로 ss.str(""); 을 작성했다. stringstream 사용법을 보며 clear()가 있어서 해당 함수가 초기화라고 생각했는데 state를 지우는 함수라고 했다. stringstream를 초기화하는 함수는 2개가 있다.

  1. ss.str("");
  2. ss.str(std::string());

이제 예쁘게 잘 나온다.

Setter

void	Zombie::setName(std::string name)
{
	this->name = name;
}

ex00의 조건 중에는 name을 private로 선언해야 했는데 zombieHorde 에서 Zombie 클래스의 name을 변경하는 것이 불가능하기 때문에 private로 선언된 변수를 변경하기 위해서는 클래스 내부에서 접근할 수 있는 public 함수로 새로 선언해야 한다. 이러한 것을 setter라고 부른다.

그렇다면 private가 아닌 public으로 선언하면 되는데 굳이 setter를 이용하는 이유는 무엇일까? CPP00에도 적었지만 외부에서 무분별하게 변수의 값을 설정하는 것을 막기 위해서다. setter를 통해 접근하면 예외처리가 가능하지만 변수로 바로 접근한다면 예외처리가 불가능하기 때문.

profile
42Seoul -soooh ~ 2022.04

0개의 댓글