본문 바로가기

Study/C C++

[두들낙서] 객체 복사

얕은 복사

 - 주소값만 복사한다

 주의 주소값만 복사하면 에러를 일으킬 수 있다

 ex) int *a = new int(5);

      int *b = new int(3);

      a = b;

      delete a;  3을 삭제한다

      delete b;  삭제된 부분을 삭제하기 때문에 에러가 난다

 

깊은 복사

 - 값을 복사한다

 - 얕은 복사로 인한 오류를 방지하기 위해 깊은 복사를 쓰는 것이 좋다

 ex) int *a = new int(5);

      int *b = new int(3);

      *a = *b;

      delete a;  5가 있던 위치에 있는 3을 삭제한다

      delete b;  기존 3을 삭제한다

 

복사 생성자

 - 객체를 생성할 때 다른 객체를 복사한다

 - 객체를 복사할 때, 멤버 포인터에서 얕은 복사가 일어나기 때문에 오버로딩해준다

 ex) String(const String &rhs) {

           strData = new char[rhs.len + 1];  null문자를 고려해 len+1만큼 할당한다

           strcpy(strData, rhs.strData);  strData에 내용을 복사한다

           len = rhs.len;  변수는 깊은 복사가 일어난다

      }

 

복사 대입 연산자

 - 객체를 생성하고 난 후, 다른 객체를 복사할 때 사용하는 연산자이다

 - 'operator=' 오버로딩을 통하여 얕은 복사를 방지한다

 주의 매개변수로 주소값을 주는것이 효율적이다  매개변수로 객체를 복사하는 복사 횟수 1번을 줄여준다

 주의 'operator=' return 값으로 주소값을 주는것이 효율적이다  return으로 발생하는 복사 횟수 1번을 줄여준다

 ex) String &operator=(const String &rhs) {  자기 자신으로 복사하는 경우 오류가 발생함으로 막아야 한다

           if (this == &rhs) return *this;

           delete[] strData;  기존 객체에 값이 들어 있었을 수 있으므로 값을 삭제해주어야 한다

           strData = new char[rhs.len + 1];

           strcpy(strData, rhs.strData);

           len = rhs.len;

           return *this;  this는 객체의 주소값이므로, *this는 객체를 반환한다

      }

 

이동 시맨틱

 - 객체가 클 때 깊은복사를 하게되면, 정적변수 생성과 해제, 비트 복사로 인해 효율이 많이 떨어진다

 - a = getName(); 같은 연산에서 함수에서 만들어진 객체가 임시객체로 복사 되고, 임시객체에서 본 객체로 복사가 된다 일어나는 복사는 총 2번 일어난다

 - 복사 생성자와 복사 대입 연산자의 깊은 복사를 얕은 복사로 만들어 사용하면 효율이 높아진다

 주의 얕은 복사는 중복 소멸자를 조심해야 한다

 

임시 객체

 - 임시 객체는 r-value이다 r-vlaue는 우변에만 존재하는 수정 불가능한 값 또는 객체

 - return이 임시 객체를 반환한다

 - 임시 객체를 참조할 수 있는 변수는 &&(변수이름)으로 사용할 수 있다

 ex) String &&r = getName();

 

이동 생성자

 - 생성자의 깊은 복사를 얕은 복사로 바꾸어 효율을 높인다

 ex) String(String &&rhs) {  r-value 참조를 매개변수로 받는다

           len = rhs.len;

           strData = rhs.strData;

           rhs.strData = NULL; rhs.strData의 참조값이 없어지기 때문에, delete[] 해도 중복으로 인한 오류가 나지 않는다

      }

 

이동 대입 연산자

 - 임시객체로 복사하는 과정에서 깊은 복사를 얕은 복사로 바꾸어 효율을 높인다

 ex) String &operator=(String &&rhs) {

          len = rhs.len;

           strData = rhs.strData;

           rhs.strData = NULL; rhs.strData의 참조값이 없어지기 때문에, delete[] 해도 중복으로 인한 오류가 나지 않는다

           return *this;  this는 객체의 주소값이므로, *this는 객체를 반환한다

      }

'Study > C C++' 카테고리의 다른 글

[두들낙서] 상속  (0) 2021.03.04
[두들낙서] 묵시적 형변환  (0) 2021.03.04
[두들낙서] 동적 할당  (0) 2021.03.04
[두들낙서] 클래스와 객체  (0) 2021.03.04
[두들낙서] C++ 스타일 문법  (0) 2021.03.03