Today
Total
Recent Posts
Recent Comments
Archives
05-19 03:21
«   2024/05   »
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
반응형
관리 메뉴

UD_park's IT story

[C++] 복사 생성자(Copy Constructor) 본문

IT - Language/C++

[C++] 복사 생성자(Copy Constructor)

kingllzn 2018. 6. 22. 08:46
반응형
SMALL

(학습 서적 이것이 C++이다에서

내용 발췌하였습니다)

 

[보기용 예제 소스 코드에서 오류 발생시에

댓글이나 방명록에 글을 남겨 주시면 수정/보완하겠습니다]

 

 

이번에는 정말 많은 시간을

투자하여 이해하고 익힌

복사 생성자(Copy Constructor)에

대해서 포스팅 해보겠습니다

 

일단 복사 생성자에 대한

정의는 다음과 같습니다

 

객체의 본사본을 생성할 때 호출되는 생성자

 - 클래스를 작성할 때 복사 생성자를 생략하면 디폴트 생성자처럼 컴파일러가 알아서 만들어 사용함

(반대로 복사 생성자를 적용하지 않으면 심각한 문제 발생할 경우도 존재함

- 클래스 내부에서 메모리를 동적 할당 및 해제하고 이를 멤버 포인터 변수로 관리하고 있는 경우)

 

글을 쓰고있는 저도 어려워

머리가 아프려고 합니다 

 

일단은 사용 문법 형태를 파악한 후

자세하고 쉽게 파악해보겠습니다

 

클래스이름(const 클래스이름 &rhs);

뒤의 매개 변수 &rhs

임의로 지었지만 대부분

저 이름을 많이 사용한다고 합니다

 

 

제가 복사 생성자 부분에서

더 다룰 것으로

 

복사 생성자 기본 선언 및 정의,

함수 호출과 복사 생성자,

깊은 복사와 얕은 복사

입니다(사실 책을 따라가는 것입니다)

 

 

그럼 첫 번째로 복사 생성자의

기본 선언과 정의 입니다

 

14번부터 19번 줄의 코드는

주석문에 나오다 시피

복사 생성자 선언과 정의입니다

 

그리고 main 함수를 보시면

31번 줄에 기본 생성자를 호출합니다

 

그리고 35번 줄의 코드는 복사 생성자를

호출하는 코드입니다

 

즉, 원본인 a를 b가 복사하여

생성 되는 것 입니다

그리고 a에 대한 참조를

&rhs가 하고있다는것을 코드로

알 수있습니다

 

기본이라 생각하기엔 조금

어려우실 수 있으나

다음 함수 호출과 복사 생성자를

보시면 좀 더 이해가 잘

되실 수 있을것 같습니다

 

전에 보시던 코드보단

훨씬 간략하기에 아마도

훨씬 복사 생성자를 이해하시기

쉬우실 겁니다

 

여기서 참고해야 할 점은

18번 줄을

 

CData(const CData Data)

{

cout << "복사 생성자 호출" << endl;

}

이렇게 쓰면 Error가 발생합니다

그 이유는 (매개변수, 인자)를 제대로

사용하지 못했기 때문입니다

 

포인터끼리 교환에서 문제가

발생하는 것과 같이 복사 생성자도

엄연히 따지면 함수이기에

인자를 매개 변수에 복사합니다

 

그러나 복사과정이

int Number = Number2;

인것처럼 계속해서 무한히

복사 생성자를 호출하고

반복하기에 Error가 발생합니다

 

이 점만 중요하게 생각하고

사용하신다면 복사 생성자를

사용하시는 동안에 큰 에러는

발생하지 않을 것 같습니다

 

 

세번째는 바로 정말

공부하면서도 뭐가 뭔지

처음에 많이 헤맸었던

깊은 복사(Deep Copy)와

얕은 복사(Shallow Copy)입니다

 

얕은 복사는 객체가 가진 값을

새로운 객체로 복사할 때

복사되는 형태가 값 그대로

복사되는 것을 의미한다

 

깊은 복사는 참조값의 복사가 아니라

참조된 객체 그 자체를 복사된 것입니다

즉, 별도의 메모리 공간에 자리 잡고

복사하고자 하는 포인터 변수가 가리키는

값을 할당합니다 

 

이제 본격적으로 코드를 보며

하나 하나씩 상세히 뜯어보겠습니다

 

 

위와 아래의 코드 사진은

같이 이어지는 코드입니다

 

위와 같이 코드를 작성한다면

아래에 있는 사진과 같이

에러가 일어납니다

 

 

그 이유는 간단합니다

위에서 DeepCopy라고

깊은 복사를 수행하는 함수는

문제 없지만 ShallowCopy라고

얕은 복사를 수행하는 함수에서

에러가 났기 때문입니다

 

얕은 복사가 에러나는 이유는

앞서 말한 에러의 이유와는 다릅니다

 

좀 더 이해하기 쉽도록

그림을 통해 설명하겠습니다

 

 

위의 그림에서 보이다 시피

얕은 복사는 두 개의 포인터가

하나의 데이터를

깊은 복사는 두 개의 포인터가

두 개의 데이터 각각을

가리킵니다

 

36, 37번 줄의 코드에서

에러가 발생한 것과 같이

에러를 발생 시킵니다

 

얕은 복사의 delete 부분에서

A를 해제하고 난 후

B를 해제 하려하는데

이미 A는 해제되어 사라진

데이터와 메모리이기 때문에

B에서 한번 더 해제 할 수가 없습니다

이런 이유에서 얕은 복사는 에러가

발생하게 됩니다

 

아래의 화면을 보시겠습니다

메인 함수에서 얕은 복사 함수

호출 부분을 주석처리하고

디버깅을 하였더니 문제없이

잘 실행 되는 모습입니다

 

즉, 얕은 복사가 아닌

깊은 복사가 더 적합한

복사 생성자 입니다

 

 

혹시 다른것에 대해 궁금하신게

있으시다면

댓글에 달아주세요

 

아는것이면 친절하게 쉽게

모르는것이면 또 제가 알아내서

친절하게 쉽게 포스팅해서

설명해드리겠습니다

반응형
LIST
Comments