[#6 열혈강의 C++]
2021-07-06
[Chapter 05] 복사 생성자
SoSimple sim1 ( 15,20 ) ;
SoSimple sim2 = sim1 ; 에서 ----ㄱ
sim2 객체에 sim1가 복사된다고 생각 할 수 있다.
ㄱ 문장은 SoSimple sim2(sim1) ; 로 묵시적 변환이 되어서 객체가 생성되는 것이다.
SoSimple ( SoSimple ©) { ~~ } 같은 생성자를 복사 생성자라 한다.
-> SoSimple ( const SoSimple ©) : num1(copy.num1) , num2(copy.num2) { ~~ }
에서 const 키워드는 원본을 손상시킬 수 있으므로 붙여준다.
디폴트 복사 생성자는 멤버 대 멤버의 복사를 진행한다. 이러한 복사를 "얕은 복사" 라고 한다.
이 복사는 멤버변수가 힙의 메모리 공간을 참조하는 경우에 문제가 생긴다.
얕은 복사는 멤버 대 멤버의 복사이다. 이렇기 때문에 A객체의 멤버변수가 어떤 문자열을 포인터 참조 할 경우,
이 객체를 복사한 B객체는 이 문자열까지 복사하지 못하고, B객체의 멤버변수가 이 문자열을 포인터 참조하게 된다.
객체의 소멸 과정에서 문제가 생기게 되는데, B객체를 소멸되면 문자열 또한 소멸된다. A객체가 가리키던 문자열은 이미 소멸된 상태이므로 A객체의 소멸이 문제가 된다.
-> 깊은 복사란 포인터로 참조하는 대상 까지 깊게 복사한다는 의미이다.
예를 들면,
Person(const Person & copy) : age(copy.age) {
name = new char[ strlen(copy.name) + 1 ] ;
strcpy( name, copy.name ) ;
의 방식으로 깊은 복사를 진행 할 수있다.
-> 메모리 공간 할당 후 문자열 복사. 그리고 할당된 메모리의 주소 값을 멤버 name 에 저장
복사 생성자의 호출 시점은
1. 기존의 객체를 이용해 새 객체를 초기화
2. Call-by-value 방식의 호출에서 객체를 인자로 전달.
3. 객체를 반환하지만, 참조형으로 반환하지 않은 경우.
-> 함수가 값을 반환하면, 별도의 메모리 공간이 할당되고(임시객체), 이 공간에 반환 값이 저장된다.
-> SoSimple SimpleFuncObj ( SoSimple ob) {
return ob;}
SoSimple tempRef = SimpleFuncObj(obj) ;
의 경우 SimpleFuncObj 함수에서 ob인자에 객체 obj가 전달되었으므로 복사생성자가 1번째 호출.
함수 내부에서 ob객체가 만들어지므로 2번째 복사 생성자가 호출.
리턴의 값이 객체지만, 참조형으로 반환이 아니므로 임시객체 형태로 ob 객체 반환 이때 3번째 호출.
의 과정을 거친다. 이때, 반환되는 임시객체에 tempRef라는 이름을 할당 해준다.