시작은 미미하나 끝은 쥬쥬하리라.

Study/Passionate C++ Programming

[열혈 C++ 프로그래밍] (5) 복사 생성자

코딩뚜벅이 2024. 1. 21. 14:40

복사 생성자

  • 복사 생성자
  • 깊은 복사와 얕은 복사
  • 복사 생성자의 호출시점

복사 생성자

객체 간의 대입 연산이 이루어지는 경우 대입 연산의 결과를 정의하는 것

-> C++은 객체 간 대입 연산의 결과를 프로그래머에게 정의 촉구
-> 복사 생성자를 정의하지 않으면 디폴트 복사 생성자가 멤버 대 멤버 복사의 형태로 정의

simple sim2(sim1)

 

 

-> simple 클래스에서 sim1 객체를 인자로 받아 생성되는 sim2 객체

 

simple(const simple &ref)

-> 의 형태로 선언, 그렇지 않으면 디폴트 복사 생성자 자동 생성
-> simple sim2=sim1; 의 형태로 대입이 일어났을 때, sim1의 변경이 sim2에 영향을 미치는 것을 방지

 

 

explicit

복사 생성자의 묵시적 호출을 제한하는 키워드

explicit simple(const simple &copy) : num1(copy.num1), num2(copy.num2) { }


-> 컴파일 에러 발생

 


 

깊은 복사와 얕은 복사

깊은 복사

할당된 메모리 공간을 참조하는 것이 아닌 포인터 변수를 복사하고 메모리 공간을 새롭게 할당하는 형태
+ 동적 메모리 할당을 위한 복사 생성자의 별도 명시가 필요
-> 생성자가 호출되고 기존의 객체가 인자의 형태로 전달되며 깊은 복사가 이루어짐

 

 

얕은 복사

포인터 변수를 복사하는 경우 기존에 할당되었던 포인터 변수의 주소를 참조하는 형태
-> 복사된 객체는 기존의 객체와 같은 메모리 공간을 가리키고 있기

 

 


 

복사 생성자의 호출 시점

복사 생성자 호출 시점
1. 기존에 생성된 객체를 이용해서 새로운 객체를 초기화하는 경우

 A obj1 = obj2;


2. 객체를 인자로 전달했는데 그것을 값으로 반환하는 경우

void Func(A obj3) { . . . }


-> A의 객체가 인자로 전달
-> Func함수를 호출하면서 obj1 객체를 인자로 전달
-> obj3라는 객체를 생성과 동시에 obj1으로 초기화하는 형태와 동일
-> void Func(A obj3) == A obj3 = obj1;


3. 객체를 반환하는데 값으로 반환하는 경우

A Func() { return obj3; }


-> 반환 시에 리턴값 obj3가 메모리 공간에 할당되어 복사가 이루어짐
-> A객체의 메모리 공간을 할당하고 obj3를 인자로 받는 생성자를 호출하는 형태

 

 

- 멤버변수n을 x로 초기화
- t1객체 값 변경을 제한하기 위해
복사생성자에서는 매개변수를 const 참조형 선언
- t1 객체의 x에는 300이 복사
- t2 객체의 n에는 t1의 n(x) 즉 300이 복사

 

 

임시 객체

해당 라인에서만 유효한 객체

Func() { return 3; }
cout<<Func<<endl;


-> Func() 함수를 출력하면 3이 반환되지만 다음 코드에서 3이라는 숫자를 출력할 수 없음
-> 여기서 3의 값을 담고 있는 Func는 임시 객체
임시 객체 생성 방법 : Temporary temp()

Temporary (100);


-> Temporary라는 클래스에 100을 인자로 전달, 객체의 이름이 없음
+ int &ref = 3; -> 상수와 임시객체는 비슷한 성향을 지님 -> 다음 코드로 넘어가면 소멸
-> const int &ref = 3;으로 참조 가능
-> const Temporary &ref = Temporary(300) 의 형태로 별도로 메모리 공간을 할당하여 개행 되어
도 접근 가능, main의 return 이후 소멸