Back-end/C++

22.03.21. 복사 생성자, const함수

giggs 2022. 4. 2. 12:08

 

복사 생성자

 

 

 

생성자란?

- 객체가 생성될 때 자동으로 호출되는 함수

 

 

생성자의 타입

  1. 기본 생성자 – 기본으로 만들 경우 작동
  2. 인자를 받는 생성자 – 인자를 전달했을 때 작동
  3. 복사 생성자 – 자신의 데이터 타입의 인자가 전달될 때 작동

 

 

 

동일한 데이터 타입의 인자를 받는 생성자 = 복사 생성자

동일한 데이터 타입이다 -  의미 : 할당된 메모리의 공간 size도 동일하고, 쪼개쓰는 방식도 동일하다는 의미

 

 

 

A타입 a객체 - value값으로 100 저장

 

 

A타입 a객체를 복사해서 A타입 b객체와 A타입 C객체 생성

 

 

 

A 데이터 타입의 객체 a를 생성해주고, value값을 100으로 세팅

 

55번 Line - A 타입의 a 객체에 있는 값이 - b에 전달될 것이다.

55번 Line - A 타입의 b 객체가 생성될 때 – a의 값 (vlaue)을 복사해서 객체가 생성된다.

 

55번 line은

56번 line처럼 호출된 거랑 동일하다고 보면 됨 - 표기법만 다르다. 

 

이처럼 객체를 복사해서 새로운 객체를 만들 경우 - 복사 생성자가 호출되어서 만들어지는 것이다.

일반적인 경우에는 컴파일러가 생성자를 자동으로 만들어 준다 - 따로 지정 필요 없다 - 

 

 


 

 

객체를 복사해서 만들 경우 - 복사 생성자가 자동으로 생성되는지 확인 

  • 일반적인 경우 – 컴파일러가 자동으로 만들어 준다 - 따로 지정 필요 없다 - 
  • 우리는 복사 생성자가  자동으로 호출되는지 확인하기 위해 복사 생성자 생성해서 확인

 

 

 

복사 생성자를 만들어준 뒤 - A객체를 복사해서 새로운 객체를 만들 경우 자동으로 생성되는지 확인해보자.

 

 

a객체를 복사한 b.c객체가 생성될 때 컴파일러가 자동으로 복사 생성자 호출해서 만들어주는것 확인

 

 

 

a객체는 클래스 타입으로 객체 만든 것이라 기본 생성자 호출 - 복사 생성자  X

b객체는 같은 데이터 타입의 a객체를 복사해서 만든 것이다. - 복사 생성자 O

c객체는 같은 데이터 타입의 a객체를 복사해서 만든 것이다. - 복사 생성자 O

 

_value의 값도 동일하게 복사돼서 생성된 것 확인 : )

 

 

 


 

 

BUT!

 

복사 생성자를 꼭 만들어 주어야 하는 경우도 있다.!  - ( 위에서 만든 것은 자동으로 호출되는지 확인용 )

 

 

  • 동적 객체 배열을 가지고 있는 객체를 복사하는 경우
  • 주소 값을 가지고 있는 객체를 복사하는 경우
  • 같은 주소 값을 사용하게 되어서 수정/갱신/삭제 오류 발생 가능
  • 복사 생성자가 필요하다.

 

 

동적 객체 배열을 가지고 있는 객체 복사하는 경우 실습

 

 

 

 

 

 

동적 객체 배열 DynamicArray 생성자와 소멸자 세팅해주기 :

- 동적 객체 배열에서는 어레이 객체 만들어지면서

- 자동으로 생성자가 호출되고, 사라질 때 자동으로 소멸자 호출되는 특징을 이용

 

- 생성자가 호출될 때 동적 객체 만들고 new int[_size]

- 생성자가 소멸될 때 반납해주는 부분 해주고. - delete [] _arr

 

 

 


 

 

 

DynamicArray 데이터 타입의 객체 dynamicarray1  생성

DynamicArray 데이터 타입의 객체 dynamicarray1을 복사해서 dynamicarray2  생성 

 

 

 

 

 


 

 

 

 

DynamicArray 데이터 타입으로 생성한 dynamicarray1  메모리 상태

 

 

 

 

 

 

dynamicarray1 메모리 안에는 _size와 _arr 이 있다.

_size의 공간에는 10이라는 값과

_arr 공간에는 2000번지라는 주소 값이 있다 

  • 2000번지는 입력받은 size 만큼 만들어 준 동적 배열의 선두 번지 주소 값

 

 

DynamicArray 데이터 타입의 객체 dynamicarray1을 복사해서 생성한 dynamicarray2  메모리 상태

 

 

 

 

 

 

dynamicarray2 메모리 안에는 _size 와 _arr 이 있다.

_size의 공간에는 10이라는 값과

_arr 공간에는 2000번지라는 주소 값이 있다 

  • 2000번지는 입력받은 size 만큼 만들어 준 동적 배열의 선두 번지 주소 값

 

 

 


 

 

 

 

dynamicArray1 복사해서 만든 dynamicArray2에서도 배열의 주소 공간 2000번지를 같이 사용한다.

 

 

이렇게 되면 작동은 되지만. 현재 논리적인 오류 상태이다

 

  • dynamicArray1에서 배열 값을 수정, 갱신, 삭제하면 dynamicArray2에서도 수정, 갱신, 삭제된다.
  • 이런 내용을 모르고  dynamicArray2에서 배열 값 사용하면 결과 값이 다르게 나오거나 오류 발생

 

  • dynamicArray1 객체가 없어질 때 소멸자 호출 -> 공간 없어짐 -> OS에 2000번지 반납 처리 
  • 그것도 모르고
  • dynamicArray2 에서는 사라진 공간에 무엇을 입력, 변경하려면 아주 큰 오류 발생 +
  • dynamicArray2 객체가 없어지는 경우 -> 소멸자 호출 -> OS에 2000번지 반납 -> OS 입장에서는 이미 없어져서 없는 공간 -> 오류 발생

 

 

 

 

이럴 경우를 대비해 복사 생성자 생성 필요!!

 

 

 

18Line 인자 값으로 DynamicArray타입 객체의 주소 값을 받겠다. 그 주소 값 dynamicArray1을  - ref에 저장

20Line - 받아 온 dynamicArray1의 size를 그대로 가져오고

22Line – 그 size 만큼 dynamicArray2만의 동적 메모리 공간을 만들어준다. new int [ _size ]

24Line - 그 공간에 dynamicArray1의 값들 그대로 카피 필요 - for

 

이러면 dynamicArray1과 dynamicArray2의 동적 객체 배열이 따로따로 만들어진 것이라 에러 안 난다!!

 

복사 생성자 개념 정리 – 같은 객체 array 가져오고 / size 가져오고 / 그만큼 공간 만들어주고/ 값 가져와서 대입

 

 


 

 

const형 

 

 

객체를 함수의 인자로 전달할 때 const 속성으로 전달하면 전달받은 객체의 값을 함수 안에서 변경 못하게 된다.

전달받은 주소 값으로 원래의 값 변경 불가능하게 하도록 해주는 방법

 

 

 

 

const형 함수 내부에서는 멤버 함수 변경 불가능

 

 

SetIndex ( ) 함수는 멤버함수이고, info( ) const 함수는 const형 함수 check!

 

 

 

함수를 만들 때 인자 값으로 객체를 받는 경우의 const 

 

 

const속성으로 인자 값이 들어오면 - 함수 내에서 멤버함수는 사용불가능 - const 함수만 사용 가능

 

 

 

 

65번 Line - 객체를 함수의 인자로 전달할 때 - const속성으로 전달하게 되면

65번 Line - 그 객체의 값을 함수 안에서 변경할 수 없다. - const 속성 없으면 전달받은 주소 값을 이용하여 접근 가능

68번 Line - 객체를 통해서 접근 가능한 멤버 함수에도 접근 불가능! 

71번 Line - const형으로 만들어 줬던 info( ) 함수에는 접근 가능!

 

 

 

함수에 const를 붙인다는 의미 = 그 함수 내에서는 멤버 함수의 값을 변경하지 않겠다는 뜻!

 

 

다른 언어에서는 이런 기능 없다!

const는 있는데 이런 메커니즘 가진 것은 없다.

 

 

 


 

 

review

이번 강의에서는 복사 생성자의 여러 가지 특징들과 const형 함수에 대하여 배웠다.



복사 생성자 

동일한 데이터 타입의 인자를 받는 생성자
일반적인 경우 자동으로 생성 -
주소 값을 가지고 있는 객체 복사할 때에는 생성자 직접 만들어줘야 한다.
복사 생성자 만들어주는 순서 : 
① 같은 객체 array 가져오고 ② size를 가져오고 ③ 그만큼 공간 만들어주고 ④ array의 값가져와서 대입



const형 함수 

객체를 함수의 인자로 전달할 경우 - const 속성으로 전달하면 -
그 함수 내에서 객체의 값 접근 불가능
전달받은 주소 값으로 원래의 값 접근 불가능, 변경 불가능하게 해주는 방법이다.
함수 뒤에 const를 추가해주면 const함수가 된다. 
함수에 const를 붙이다는 의미 = 그 함수 내에서는 멤버 함수의 값을 변경하지 않겠다는 뜻이다.



복사 생성자 정리해 놓으니까 간단하네ㅎㅎ
복사 생성자를 직접 만들어주어야 하는 경우를 배울 때 그냥 주소 값을 복사해가면 같은 주소 값으로 접근해서 오류가 나니까 만들어줘야 한다 에서 끝난 것이 아니라.
왜 그렇게 되는지, 어떻게 해결해줘야 하는지 내부 작동 원리를 설명해 주셔서 좋았다.
그냥 주소 값을 복사하면 안 되니까 만들어줘야 한다는 암기 느낌이 아니라
새로운 공간을 만들어주고 거기에 대입을 해줘야 한다는 식으로 이해하고 사용하니 느낌이 달랐다.


const형 부분에서는 그냥 상수나 변경 불가능한 함수로 사용하는 것이라고 알고 있었는데
C++에서는
함수에 const를 해주면 - 그 함수 안에서는 멤버 변수를 변경하지 않겠다는 의미와 
함수의 인자 값으로 const 속성이 들어오면 - 함수 내부에서는 다른 함수는 사용 불가능, const형 함수만 사용 가능이라는 개념도 있다는 것이 흥미로웠다. 접근제어자 역할인가?ㅎㅎ

실제 어떤 상황에 사용하는지는 아직 모르겠지만 기능과 특징에 대해 잘 알아놓기!