
implement the two following functions:
• Zombie* newZombie( std::string name );
It creates a zombie, name it, and return it so you can use it outside of the function
scope.
• void randomChump( std::string name );
It creates a zombie, name it, and the zombie announces itself
class Zombie {
private:
std::string _name;
public:
Zombie(std::string name);
~Zombie();
// 생성/소멸 시 디버깅 메시지 출력
void announce();
};
Zombie* newZombie(std::string name) {
Zombie* ptr = new Zombie(name);
return ptr;
}
void randomChump(std::string name) {
Zombie myZombie(name);
myZombie.announce();
}
int main() {
Zombie myZombie("stack1"); // 스택 할당
randomChump("stack2"); // 스택 할당 후 자동 소멸
Zombie* heap = newZombie("heap"); // 힙 할당
heap->announce();
delete heap; // 수동 메모리 해제
return 0;
}
stack1 is created // 1️⃣ 스택 좀비 생성
stack2 is created // 2️⃣ randomChump 안에서 좀비 생성
stack2: BraiiiiiiinnnzzzZ... // 2️⃣ randomChump 안에서 announce 호출
stack2 is dead // 2️⃣ randomChump 함수 종료로 소멸자 호출
heap is created // 3️⃣ 힙 좀비 생성
heap: BraiiiiiiinnnzzzZ... // 4️⃣ announce 호출
heap is dead // 5️⃣ delete로 인한 소멸자 호출
stack1 is dead // 6️⃣ main 함수 종료로 스택 좀비 소멸
스택 할당
객체의 수명이 특정 스코프로 제한될 때
간단하고 빠른 메모리 할당이 필요할 때
자동 메모리 관리가 필요할 때
힙 할당
객체가 함수 범위를 벗어나서 존재해야 할 때
런타임에 메모리 크기가 결정될 때
큰 크기의 객체를 다룰 때

Implement the following function in the appropriate file:
Zombie* zombieHorde( int N, std::string name );
class Zombie {
private:
std::string _name;
public:
Zombie();
~Zombie();
void setName(std::string name);
void announce();
};
Zombie* zombieHorde(int N, std::string name) {
Zombie* zombies = new Zombie[N]; // N개의 좀비 배열 생성
for (int i = 0; i < N; i++) {
zombies[i].setName(name);
}
return zombies;
}
new Zombie[N]을 사용해 배열 형태로 동적 할당
int main() {
Zombie* zombies = zombieHorde(5, "Foo");
for (int i = 0; i < 5; i++) {
zombies[i].announce();
}
delete[] zombies;
return 0;
}
delete[]를 사용해 메모리 해제
Foo: BraiiiiiiinnnzzzZ... // 첫 번째 좀비
Foo: BraiiiiiiinnnzzzZ... // 두 번째 좀비
Foo: BraiiiiiiinnnzzzZ... // 세 번째 좀비
Foo: BraiiiiiiinnnzzzZ... // 네 번째 좀비
Foo: BraiiiiiiinnnzzzZ... // 다섯 번째 좀비
Foo is dead // 소멸자 호출 (5번)
Foo is dead
Foo is dead
Foo is dead
Foo is dead
배열 소멸 시 각 객체의 소멸자 호출 보장
동적할당 시 소멸자
// 단일 객체
Zombie* heap = new Zombie("heap");
delete heap; // delete 시 소멸자 호출
// 객체 배열
Zombie* zombies = new Zombie[5];
delete[] zombies; // 배열의 각 객체마다 소멸자 호출
스택 할당 시 소멸자
void foo() {
Zombie stack("stack"); // 생성자 호출
} // 함수 종료 시 자동으로 소멸자 호출
int main() {
Zombie z("main"); // 생성자 호출
foo();
return 0; // main 함수 종료 시 z의 소멸자 호출
}
스코프를 벗어날 때 자동으로 소멸자 호출
별도의 delete 필요 없음
프로그램 종료 시 남아있는 스택 객체들의 소멸자가 호출됨
int main() {
Zombie a("A"); // 스택 객체 생성
Zombie* b = new Zombie("B"); // 힙 객체 생성
{
Zombie c("C"); // 새로운 스코프의 스택 객체
} // C의 소멸자 호출
delete b; // B의 소멀자 호출
return 0; // A의 소멸자 호출
}

Write a program that contains
• A string variable initialized to "HI THIS IS BRAIN".
• stringPTR: A pointer to the string.
• stringREF: A reference to the string.
Your program has to print
• The memory address of the string variable.
• The memory address held by stringPTR.
• The memory address held by stringREF.
And then
• The value of the string variable.
• The value pointed to by stringPTR.
• The value pointed to by stringREF.
int main()
{
std::string str = "HI THIS IS BRAIN";
std::string *stringPTR = &str; // 포인터
std::string &stringREF = str; // 참조자
// 메모리 주소 출력
std::cout << "문자열 변수의 메모리 주소 : " << &str << std::endl;
std::cout << "stringPTR이 가리키는 메모리주소 : " << stringPTR << std::endl;
std::cout << "stringREF가 참조하는 메모리주소 : " << &stringREF << std::endl;
// 값 출력
std::cout << "문자열 변수의 값 : " << str << std::endl;
std::cout << "stringPTR이 가리키는 값 : " << *stringPTR << std::endl;
std::cout << "stringREF가 참조하는 값 : " << stringREF << std::endl;
}
문자열 변수의 메모리 주소 : 0x7fff5fbff6e0
stringPTR이 가리키는 메모리주소 : 0x7fff5fbff6e0
stringREF가 참조하는 메모리주소 : 0x7fff5fbff6e0
문자열 변수의 값 : HI THIS IS BRAIN
stringPTR이 가리키는 값 : HI THIS IS BRAIN
stringREF가 참조하는 값 : HI THIS IS BRAIN
| 포인터 | 참조자 | |
|---|---|---|
| 초기화 | 나중에 초기화 가능 | 선언과 동시에 초기화 필요 |
| 재할당 | 다른 주소로 변경 가능 | 한번 참조하면 변경 불가 |
| null | null 가능 | null 불가능 |

Implement a Weapon class that has
• A private attribute type, which is a string.
• A getType() member function that returns a const reference to type.
• A setType() member function that sets type using the new one passed as parameter.
create two classes
HumanA and HumanB. They both have a Weapon and a
name. They also have a member function attack() that displays (of course, without the angle brackets):
<name> attacks with their <weapon type>
HumanA and HumanB are almost the same except for these two tiny details
• While HumanA takes the Weapon in its constructor, HumanB doesn’t.
• HumanB may not always have a Weapon, whereas HumanA will always be armed.
class Weapon {
private:
std::string _type;
public:
const std::string &getType(); // 참조자 반환
void setType(std::string str);
Weapon(std::string type);
};
class HumanA {
private:
std::string _name;
Weapon &_weapon; // 참조자로 무기 소유
public:
HumanA(std::string name, Weapon &humanWeapon);
void attack();
};
class HumanB {
private:
std::string _name;
Weapon *_weapon; // 포인터로 무기 소유
public:
HumanB(std::string name);
void setWeapon(Weapon &weapon);
void attack();
};
// 참조자 사용 (항상 무기를 가짐)
HumanA::HumanA(std::string name, Weapon &humanWeapon)
: _name(name), _weapon(humanWeapon) {} // 초기화 필수
// 포인터 사용 (무기를 가질 수도, 안 가질 수도 있음)
HumanB::setWeapon(Weapon &weapon) {
_weapon = &weapon; // 나중에 무기 설정 가능
}
HumanB::HumanB(std::string name) : _name(name) {}
int main() {
{
Weapon club = Weapon("crude spiked club");
HumanA bob("Bob", club);
bob.attack(); // "Bob attacks with their crude spiked club"
club.setType("some other type of club");
bob.attack(); // "Bob attacks with their some other type of club"
}
{
Weapon club = Weapon("crude spiked club");
HumanB jim("Jim");
jim.setWeapon(club);
jim.attack(); // "Jim attacks with their crude spiked club"
club.setType("some other type of club");
jim.attack(); // "Jim attacks with their some other type of club"
}
}
선언과 동시에 초기화 필요
null이 될 수 없음
한번 참조하면 다른 객체 참조 불가
HumanA는 항상 무기를 가져야 할 때 적합
나중에 초기화 가능
null이 될 수 있음
다른 객체를 가리키도록 변경 가능
HumanB는 무기를 선택적으로 가질 수 있을 때 적합
참조자: 항상 유효한 객체가 필요한 경우
포인터: 선택적이거나 변경 가능한 관계에 적합

create a Harl class with the following private member functions:
• void debug( void );
• void info( void );
• void warning( void );
• void error( void );
Harl also has a public member function that calls the four member functions above
depending on the level passed as parameter:
void complain( std::string level );
Harl has to complain without using a forest of if/else if/else. It doesn’t think twice!
class Harl {
private:
void debug();
void info();
void warning();
void error();
public:
void complain(std::string level);
};
void Harl::complain(std::string level) {
// 함수 포인터 배열 선언
void (Harl::*functions[4])(void) = {
&Harl::debug,
&Harl::info,
&Harl::warning,
&Harl::error
};
std::string levels[4] = {"DEBUG", "INFO", "WARNING", "ERROR"};
// 레벨에 맞게 함수 호출
for (int i = 0; i < 4; i++) {
if (level == levels[i]) {
(this->*functions[i])();
return;
}
}
}
int main() {
Harl harl;
harl.complain("DEBUG"); // Debug 메시지 출력
harl.complain("INFO"); // Info 메시지 출력
harl.complain("WARNING"); // Warning 메시지 출력
harl.complain("ERROR"); // Error 메시지 출력
return 0;
}
ex05에서 if, else if의 제한이 있었다면 여기선 switch
void Harl::complain(std::string level) {
void (Harl::*functions[4])(void) = {
&Harl::debug,
&Harl::info,
&Harl::warning,
&Harl::error
};
std::string levels[4] = {"DEBUG", "INFO", "WARNING", "ERROR"};
int n;
for (n = 0; n < 4; n++) {
if (level == levels[n])
break;
}
switch (n) {
case 0:
(this->*functions[0])(); // DEBUG
case 1:
(this->*functions[1])(); // INFO
case 2:
(this->*functions[2])(); // WARNING
case 3:
(this->*functions[3])(); // ERROR
break;
default:
std::cout << "[ Probably complaining about insignificant problems ]" << std::endl;
break;
}
}
int main(int ac, char **av) {
Harl harl;
if (ac != 2) {
std::cout << "Wrong Type" << std::endl;
exit(EXIT_FAILURE);
}
harl.complain(av[1]);
return 0;
}
./harl DEBUG
[ DEBUG ]
I love having extra bacon for my 7XL-double-cheese-triple-pickle-specialketchup burger.
I really do!
.
.
.
[ ERROR ]
This is unacceptable! I want to speak to the manager now.
./harl INFO
[ 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 WARINING
...
./harl ERROR
[ ERROR ]
This is unacceptable! I want to speak to the manager now.
./harl something
[ Probably complaining about insignificant problems ]
./harl
Wrong Type