갓똥
나는야 프로그래머
갓똥
전체 방문자
오늘
어제
  • 분류 전체보기 (186)
    • 프로그래밍 (146)
      • 자바 (9)
      • 안드로이드 (2)
      • 유니티 (20)
      • C++ (38)
      • C# (56)
      • HTML (2)
      • 파이썬 (3)
      • 자료구조 (2)
      • 알고리즘 (0)
      • 문제풀이 (4)
      • 디자인 패턴 (7)
      • 카카오톡 봇 (1)
      • 엑셀 (1)
      • 기타 (1)
    • 게임 (21)
      • 테일즈위버 (0)
      • 카이로소프트 (1)
      • 순위 (19)
      • 기타 (1)
    • 일상 (13)
      • 카페 (1)
      • 방탈출 (12)
    • 기타 (6)
      • 웃긴자료 (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • c# collection
  • c# Thread
  • Unity Graph
  • c# delegate
  • c# 코루틴
  • 전세계 게임 매출
  • 롤 골드그래프
  • C++ 소멸자
  • 게임매출순위
  • 유니티 그래프 그리기
  • pc게임 순위
  • C++ 상속
  • 강남 방탈출
  • 모바일 게임 순위
  • C# 예외 처리
  • 유니티 그래프
  • 유니티 골드그래프
  • 자바
  • 글로벌게임매출
  • 게임 디자인 패턴
  • pc 게임 순위
  • C++
  • 알고리즘
  • C# boxing
  • C++ virtual
  • 2020년 게임 매출
  • 게임 매출 순위
  • 전세계게임매출순위
  • c# coroutine
  • c# unboxing

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갓똥

나는야 프로그래머

프로그래밍/C++

[C++] 객체의 복사 방법

2019. 11. 13. 23:29
728x90
반응형

1. 객체의 복사 방법

#include <iostream>
#include <cstring>

class Person {
    char* name;
    int   age;
public:
    Person(const char* n, int a) : age(a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }
    ~Person() { delete name; }
};

int main() {
    Person p1("kim", 20);
    Person p2 = p1;
}

  ① 얕은 복사란? (Shallow Copy)

    => 클래스 안에 포인터 멤버가 있을 때 디폴트 복사 생성자가

    => 메모리 자체를 복사하지 않고 주소만 복사 하는 현상

 

#include <iostream>
#include <cstring>

class Person {
    char* name;
    int   age;
public:
    Person(const char* n, int a) : age(a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }
    ~Person() { delete name; }
    
    Person(const Person& p) : age(p.age) {
        // 포인터는 복사 하지말고, 새롭게 메모리 할당
        name = new char[strlen(p.name) + 1];
        strcpy(name, p.name);
    }
};

int main() {
    Person p1("kim", 20);
    Person p2 = p1;
}

  ② 깊은 복사 (Deep Copy)

    => 클래스 안에 포인터 멤버가 있을 때 

    => 메모리 주소를 복사 하지 말고 메모리 자체의 복사본을 만드는 기술

 


2. 단점 및 해결책

  ① 깊은 복사 (Deep Copy)의 단점

    => 객체를 여러 번 복사하면 동일한 자원(이름)이 메모리에 여러 번 놓이게 된다.

    => 자원의 크기가 큰 경우 메모리 낭비가 발생.

 

  ② 참조 계수 (reference counting)

    => 여러 객체가 하나의 자원을 공유하게 한다.

    => 단, 몇 명의 객체가 자원을 사용하는지 개수를 관리한다.

 


3. 참조 계수 방법

#include <iostream>
#include <cstring>

class Person {
    char* name;
    int   age;
    int*  ref;
public:
    Person(const char* n, int a) : age(a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
        
        // ref = new int(1); - 아래와 동일 코드
        ref = new int;
        *ref = 1;
    }
    ~Person() { 
        // 참조 계수 기반인 경우의 소멸자
        if( --(*ref) == 0 ) {
            delete[] name;
            delete ref;
        }
    }
    
    Person(const Person& p) : name(p.name), age(p.age), ref(p.ref) {
        ++(*ref);
    }
};

int main() {
    Person p1("kim", 20);
    Person p2 = p1;
}

 

멤버 데이터 / 생성자 / 복사 생성자 / 소멸자가 바뀌었다.

  ① 참조 계수 (reference counting)에서 좀 더 생각해야 할 점

    => p1 객체가 자신의 이름을 변경하면 어떻게 될까?

    => p2의 이름은 변경되면 안되므로 공유 했던 자원은 분리되어야 한다.

        -> 참조 계수도 마찬가지로 분리되어야 한다.

    => 멀티 스레드 환경에서는 동기화의 오버헤드가 추가된다.

 


4. 이외의 복사 기법들

4.1 복사 금지

#include <iostream>
#include <cstring>

class Person {
    char* name;
    int   age;
public:
    Person(const char* n, int a) : age(a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
    }
    ~Person() { delete name; }
    
    Person(const Person& p) = delete;
};

int main() {
    Person p1("kim", 20);
    Person p2 = p1;  // 컴파일 에러가 나오게 하자.
}

  ① 복사 금지

    => 객체를 복사하지 못하게 하자는 의도

    => 복사 새성자를 delete 한다.

 

4.2 using STL

#include <iostream>
#include <cstring>
#include <string>

class Person {
    std::string name;
    int   age;
public:
    Person(const std::string n, int a) : name(n), age(a) {
    }
};

int main() {
    Person p1("kim", 20);
    Person p2 = p1;
}

  ① 문자열이 필요하면 STL의 string클래스를 사용하자.

    => 동적 메모리 할당을 할 필요 없다.

    => string이 내부적으로 자원을 관리해준다.

    => int 변수처럼 사용하면 된다.

728x90
반응형

'프로그래밍 > C++' 카테고리의 다른 글

[C++] static member function  (0) 2019.11.17
[C++] static member data  (0) 2019.11.14
[C++] 복사 생성자 (copy constructor)  (0) 2019.11.07
[C++] explicit 생성자  (0) 2019.11.06
[C++] 초기화 리스트 (member initializer list)  (4) 2019.11.05
    '프로그래밍/C++' 카테고리의 다른 글
    • [C++] static member function
    • [C++] static member data
    • [C++] 복사 생성자 (copy constructor)
    • [C++] explicit 생성자
    갓똥
    갓똥
    공부하며 알아가는 내용을 정리해 봅니다.

    티스토리툴바