전에 하던 그 생성자가 아니라, C++스러운 생성자를 만들어보자.
#include <iostream>
class Marine{
int hp;
int coord_x, coord_y;
int damage;
bool is_dead;
public :
Marine();
Marine(int x, int y);
int attack();
void be_attacked(int damage_earn);
void move(int x, int y);
void show_status();
};
Marine::Marine() :
hp(50), coord_x(0), coord_y(0),
damage(5), is_dead(false){}
Marine::Marine(int x, int y) :
coord_x(x), coord_y(y),
hp(50), damage(5), is_dead(false){}
void Marine::move(int x, int y) {
coord_x = x;
coord_y = y;
}
int Marine::attack() { return damage; }
void Marine::be_attacked(int damage_earn) {
hp -= damage_earn;
if (hp <= 0) is_dead = true;
}
void Marine::show_status() {
std::cout << " *** Marine *** " << std::endl;
std::cout << " Location : ( " << coord_x << " , " << coord_y << " ) "
<< std::endl;
std::cout << " HP : " << hp << std::endl;
}
int main() {
Marine marine1(2, 3);
Marine marine2(3, 5);
marine1.show_status();
marine2.show_status();
}
익숙하지 않은 생성자 친구가 눈에 보인다.
Marine::Marine() :
hp(50), coord_x(0), coord_y(0),
damage(5), is_dead(false){}
Marine::Marine() {
hp = 50;
coord_x = coord_y = 0;
damage = 5;
is_dead = false;
}
생성자 리스트
: hp(50), coord_x(0), coord_y(0),
damage(5), is_dead(false){}
생성자 이름 : var1(args), var2(args){}
C에서 쓰던 그 static 맞다.
클래스에서도 사용가능하고, C랑 똑같이 공유가 되고, main문 종료전까지 계속 살아있다.
class Marine{
static int total_marine_num;
int hp;
int coord_x, coord_y;
int damage;
bool is_dead;
const int default_damage;
public :
Marine();
Marine(int x, int y);
Marine::Marine(int x, int y, int default_damage);
int attack();
void be_attacked(int damage_earn);
void move(int x, int y);
void show_status();
~Marine() {total_marine_num--;}
};
int Marine::total_num = 0;
Marine::Marine() :
hp(50), coord_x(0), coord_y(0),
damage(5), is_dead(false), default_damage(5){total_marine_num++;}
...
int Marine::total_marine_num = 0;
이 static 멤버변수를 이렇게 사용한다.
Marine::Marine() :
hp(50), coord_x(0), coord_y(0),
damage(5), is_dead(false), default_damage(5){total_marine_num++;}
~Marine() {total_marine_num--;}
class Marine{
static int total_marine_num;
int hp;
int coord_x, coord_y;
int damage;
bool is_dead;
const int default_damage;
public :
Marine();
Marine(int x, int y);
Marine::Marine(int x, int y, int default_damage);
int attack();
void be_attacked(int damage_earn);
void move(int x, int y);
void show_status();
static void show_total_marine();
~Marine() {total_marine_num--;}
};
...
void Marine::show_total_marine() {
std::cout << "전체 마린 수 : " << total_marine_num << std::endl;
}
...
// main()
Marine::show_total_marine();
this 는 객체 자신을 가리키는 키워드이다.
class Marine{
static int total_marine_num;
const static int i =0;
int hp;
int coord_x, coord_y;
int damage;
bool is_dead;
const int default_damage;
public :
Marine();
Marine(int x, int y);
Marine::Marine(int x, int y, int default_damage);
int attack();
Marine& be_attacked(int damge_earn);
void move(int x, int y);
void show_status();
static void show_total_marine();
~Marine() {total_marine_num--;}
};
...
Marine& Marine::be_attacked(int damage_earn) {
hp -= damage_earn;
if (hp <= 0) is_dead = true;
return *this;
}
...
// main()
marine2.be_attacked(marine1.attack()).be_attacked(marine1.attack());
이런식으로 쓰인다.
Marine& Marine::be_attacked(int damage_earn) {
hp -= damage_earn;
if (hp <= 0) is_dead = true;
return *this;
}
이친구의 변수 hp를 this->hp라고 변경해도, 위의 함수와 의미는 같다.
Marine& Marine::be_attacked(int damage_earn) {
this->hp -= damage_earn;
if (hp <= 0) is_dead = true;
return *this;
}
근데 함수 리턴값이 Marine& 인데, 이 레퍼런스(별명, alias)를 리턴한다는 게 무슨뜻일까?
#include <iostream>
class A{
int x;
public:
A(int c) : x(c) {}
int& access_x() {return x;}
int get_x() {return x;}
void show_x() {std::cout<<x<<std::endl;}
};
int main(){
A a(5);
a.show_x();
int& c = a.access_x();
c=4;
a.show_x();
int d = a.access_x();
d=3;
a.show_x();
// 오류코드
// int& e = a.get_x();
// e = 2;
// a.show_x();
int f = a.get_x();
f = 1;
a.show_x();
}
여기서 int를 리턴하는 'get_x()' 함수와, int의 레퍼런스를 리턴하는 'access_x()'함수가 사용됨.
아으 헷갈려.. 어케 돌아가는지 차근차근 보자
int& c = a.access_x();
c = 4;
a.show_x();
레퍼런스를 리턴하는 함수는 그 함수 부분을 원래의 그 멤버변수로 치환했다고 생각해도
상관없음. int& c = x; // int x의 새 별명은 c
그렇담 int 형에 레퍼런스를 넣었는데 컴파일 에러가 안나오는 걸까
int d = a.access_x();
d=3;
a.show_x();
d=3;
을 넣었을 때, 객체에 x값이 변하지 않는게 당연하다.에러가 나온 코드를 확인해보자.
int& e = a.get_x();
e = 2;
a.show_x();
int& e = x(지역변수로 복사된 x);
마지막으로 확인해볼 친구는 int형에 객체에서 int형 값을 받아온 경우를 보자.
int f = a.get_x();
f = 1;
a.show_x();
f=1
을 해도 값이 객체의 맴버값이 바뀌진 않는다.이제 다시 Marine예제로 가보자.
Marine& Marine::be_attacked(int damage_earn) {
this->hp -= damage_earn;
if (this->hp <= 0) this->is_dead = true;
return *this;
}
*this
를 리턴받았다.(*this).멤버변수
를 this->멤버변수
처럼 써준 것이었다. *this
는 객체 자신을 의미한다.그렇담 이 부분에서 어떤일이 벌어질까
marine2.be_attacked(marine1.attack()).be_attacked(marine1.attack());
Marine& 타입이 아니라, Marine 타입으로 *this
를 리턴한다면 어떻게 될까?
Marine Marine::be_attacked(int damage_earn) {
this->hp -= damage_earn;
if (this->hp <= 0) this->is_dead = true;
return *this;
}
그렇담 이 부분에서 어떤일이 벌어질까
marine2.be_attacked(marine1.attack()).be_attacked(marine1.attack());
&Marine의 *this
를 가져온게 아니라 그냥 Marine의 *this
를 가져와서 동작한다*this
를 리턴한다.아니 그럼 위에 &Marine 의 *this
는 어떻게 두번 attack() 이 들어간거야?
class Marine {
static int total_marine_num;
const static int i = 0;
int hp;
int coord_x, coord_y;
bool is_dead;
const int default_damage;
public:
Marine();
Marine(int x, int y);
Marine(int x, int y, int default_damage);
int attack() const; // <- const 함수
Marine& be_attacked(int damage_earn);
void move(int x, int y);
void show_status();
static void show_total_marine();
~Marine() { total_marine_num--; }
};
...
int Marine::attack() const { return default_damage; }
(기존 함수 정의) const;
이렇게 사용한다.따라하자 씹어먹는 C++