본문 바로가기
Programming/C++

C++ 캡슐화, 디폴트 생성자, new, 복사생성자

by 꿈꾸는 띵땅근 2020. 12. 27.
학습 내용
1. 캡슐화
2. 디폴트 생성자 주의!
3. new
4. 복사생성자

1. 캡슐화

food 는 Animal의 private으로 선언되어있어서, 외부에서 값을 변경할 수 없다. 오로지, 메서드를 통해서 변경가능. 

이렇게 하는 이유는,

1. food data를 외부에서 임의로 변경하는 것을 막기 위해

2. food를 증가시키면 멤버변수 weight도 증가시키고 싶은데, 이 두가지 작업을 한방에 수행하기 위해서. 

즉, 

이렇게 하나하나 하지 말자고.. 이러면 개발자가 작업process를 다 알아야 함.

 


2. 디폴트 생성자 사용 주의사항!

- 올바른 선언 방법 2가지

- 잘못된 선언 방법

디폴트 생성자는, 생성자가 받는 인자가 없으므로, 모양새가 함수처럼 되어버릴 수 있다. 

위와같이 잘못된 선언을 하면, return형이 Date인 함수가 만들어진다. 


- 참고

일반적인 객체 생성 모습


3. new

- 메모리 동적할당. 

- 메모리 첫번째 주소값을 가리키는 포인터를 리턴

- 생성자 자동 호출


4. 복사생성자

- 쓰는 이유 : 디폴트 복사생성자가 있음에도 왜 복사생성자를 선언해줘야 할까?

예를들어, 

class Photo_Cannon {
	int coord_x, coord_y;
	int hp, shield;
	int damage;
    char* name;
    
public:
	Photo_Cannon(int x, int y);
	~Photo_Cannon();
	void show_status();

};
Photo_Cannon::Photo_Cannon(int x, int y) {
	coord_x = x;
	coord_y = y;
}
void Photo_Cannon::show_status(){
	cout << "Location : (" << coord_x << ", " << coord_y << ")" << endl;
	cout << "Hp : " << hp << endl;
}



int main() {
	Photo_Cannon pc1(3, 3);
	Photo_Cannon pc2(pc1);
	Photo_Cannon pc3 = pc2;

	pc1.show_status();
	pc2.show_status();
	pc3.show_status();


	return 0;
}

 이러면 런타임에러 난다. 왜냐면, Photo_Cannon pc3 = pc2; 이걸 하면 아래의 디폴트 복사생성자가 실행되어, 

Photon_Cannon::Photon_Cannon(const Photon_Cannon& pc) {
  hp = pc.hp;
  shield = pc.shield;
  coord_x = pc.coord_x;
  coord_y = pc.coord_y;
  damage = pc.damage;
  name = pc.name;
}

pc3과 pc2가 name부분에서 같은 메모리를 가리키는, 얕은복사가 이뤄졌기 때문. 

이게 왜 문제냐, 

main문 끝날때쯤, 소멸자가 실행되어 메모리 delete하는데, pc3 먼저 없애버리게 되면, pc2는 해당 주소로 가도 지울게 없어져버림. (사실, 애초에 지워진 메모리에 접근하는거 자체가 오류임)

 

따라서, 아래와 같이 복사생성자를 선언함으로써, 새롭게 이름을 동적할당 할 수 있게끔 해줘야한다. 

Photon_Cannon::Photon_Cannon(const Photon_Cannon &pc) {
  std::cout << "복사 생성자 호출! " << std::endl;
  hp = pc.hp;
  shield = pc.shield;
  coord_x = pc.coord_x;
  coord_y = pc.coord_y;
  damage = pc.damage;

  name = new char[strlen(pc.name) + 1];
  strcpy(name, pc.name);
}

결과적으로 이런식으로 되는것이다. 

 


출처
https://modoocode.com/172
 

씹어먹는 C++ - <4 - 1. 이 세상은 객체로 이루어져 있다>

 

modoocode.com

https://modoocode.com/173
 

씹어먹는 C++ - <4 - 2. 클래스의 세계로 오신 것을 환영합니다. (함수의 오버로딩, 생성자)>

 

modoocode.com

 

'Programming > C++' 카테고리의 다른 글

void 포인터  (0) 2021.03.12
Class 객체 선언 방식 2가지  (0) 2021.01.01
구조체  (0) 2020.12.27
Literal, 참조 / "문자열"이 왜 그렇게 골치아픈가  (0) 2020.12.27
C++ 코드최적화  (0) 2020.12.26

댓글