달력

10

« 2018/10 »

  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  •  
  •  
  •  

'얕은 복사'에 해당되는 글 1

  1. 2010.03.21 복사 생성자, 디폴트 생성자 그리고 디폴트 복사 생성자.






복사 생성자,
디폴트 생성자,
디폴트 복사 생성자,
그리고 디폴트 소멸자까지

쭈욱~ 둘러 보자.

사실 다 따로따로 포스팅 할까 하다가

아무리 봐도 한번에 설명하는게 좀더 나을것 같다는 생각이 든다.

자 일단 쉬운것 부터

디폴트 생성자, 디폴트 소멸자

class를 생성할 때에 우리는 소멸자를 만들 수도
만들지 않을 수도
생성자를 만들 수도
만들지 않을 수도 있다.

이것은 당연한 것이다.

하지만 컴파일러는 만들지 않으면 기본적으로 만들어 준다.

그게 중요하다는 거다.





하지만 한가지 주의할 점은 프로그래머가 생성자를 하나라도 생성하게 된다면,
디폴트 생성자는 생성 되지 않는 다는 것이다.
자, 여기 까지 봤으면 일단 복사 생성자에 대해서 알아 보자.


그렇다면 컴파일 하는 동안 무슨 일이 벌어 진 것인가.
그것은 이것과 같다.

그렇다 복사 생성자라는 것이 자동으로 생성되어
b.n에 a.n을 넣어 준 것이다.
여기 까지 이해 하고 나면 이제 디폴트 복사 생성자에 대한 문제를 알아 보아야 한다.
디폴트 복사 생성자. 무엇이 문제인가.
일단 가장 첫번째,
디폴트 생성자는 생성자가 클래스 내부에 1개라도 선언되어 있으면 생성되지 않는다고 하였지만,
디폴트 복사 생성자는 그렇지 않다는 것이다.
그 어떤 상황에서도
AAA b(a);
같은 상황으로 선언하면 그 클래스에 생성자가 존재 하던 그렇지 않던(같은 복사 생성자는 제외)
디폴트 복사 생성자를 만든다는 것이다.
그렇다면 이게 어떤 문제를 일으 킬 수 있는가.



왜 이런 문제가 발생 하는가,
그것에 대해선,
디폴트 복사 생성자때문이다. 라고 말할 수 있는데,
실제로 컴파일러가 자동으로 만들어 주는 디폴트 복사 생성자에 대해서
그대로 타이핑 해보면 다음과 같다.


흔히 얕은 복사라 하여,
같은 메모리를 2곳에서 쓰다 보니
소멸자에서 첫번째 메모리 삭제 이후
다시 똑같은 곳을 삭제해 주고 있다.
당연히 문제가 생길 수 밖에 없는 것!
그래서 복사 생성자에서 깊은 복사를 할 수 있도록 꼭 추가해 주어야 한다.
(사실 동적 할당이 아니라면 디폴트 복사 생성자를 써도 큰 문제가 되질 않는다.)


사실 별것 아닌데 마치 거대한 위기가 온듯 설명 했지만,
알고 있는것과 모르는 것의 차이는 크기에,
그렇다면
AAA b(a);
선언만 하지 않으면 되는것 아닌가 라고 생각 할 수도 있지만,
그건 또 아니다.
디폴트 복사 생성자가 생성되는 경우는 3가지가 있는데,
지금 처럼 기존의 생성된 객체로 새로운 객체를 초기화 하는 경우가 첫번째,

두번째로는,
함수 호출 시에 객체를 값에 전달 하는 경우( call by value )이다.


그리고 마지막 세번째는 함수의 리턴에 의한 복사 생성자의 호출 이다.
소스를 보자.


참 어렵다. 하지만 메모리에 구조를 좀 파악했다면,
그렇게 까지 힘든 내용은 아니였던 것 같다.

'프로그래밍 > C++' 카테고리의 다른 글

static  (0) 2010.03.24
멤버 이니셜 라이저(member initializer)  (0) 2010.03.23
복사 생성자, 디폴트 생성자 그리고 디폴트 복사 생성자.  (0) 2010.03.21
friend  (0) 2010.03.21
this 포인터  (0) 2010.03.21
객체 포인터 배열  (0) 2010.03.21
Posted by 안식의후크