nakka soft world !
Object Copy 본문
Object Copy
Swallow Copy & Deep Copy
1. 얕은 복사
class People
{
private:
char* name;
int age;
public:
People(char* n, int a) : age(a)
{
name = new char[strlen(n)+1];
strcpy(name, n);
}
~People()
{
delete[] name;
}
};
int main()
{
People p1("kim", 2);
People p2(p1); // runtime error.
// 복사 생성자 호출.
}
어떠한 클래스가 포인터를 가지고 있을때 default복사 생성자는 동째로 복사 하지 않고 주소 만 복사함.(얕은 복사) 소멸될때 하나의 객체가 메모리를 해제 하면 다른 객체가 소멸하려고 접근시 에러발생.
2. 얕은 복사 해결책 : 깊은 복사 (Deep Copy)
메모리 주소만 카피 하지 않고 메모리 전체를 카피함.
class People
{
private:
char* name;
int age;
public:
People(char* n, int a) : age(a)
{
name = new char[strlen(n)+1];
strcpy(name, n);
}
~People()
{
delete[] name;
}
People(const People& p) : age(p.age)
{
name = new char[strlen(p.name)+1];
strcpy(name, p.name);
}
};
int main()
{
People p1("kim", 2);
People p2(p1); // 복사 생성자 호출
}
3. 얕은 복사 해결책 : 참조 계수 (Reference Counting)
깊은 복사의 문제점. 메모리에 중복 내용이 들어가서 메모리 낭비가 발생함.
Swallow Copy 에서 Count를 두고 참조 Count로 해지할지 말지 결정함.
class People
{
private:
char* name;
int age;
int* ref; // 참조 계수
public:
People(char* n, int a) : age(a)
{
name = new char[strlen(n)+1];
strcpy(name, n);
ref = new int;
*ref = 1;
}
People(const People& p) : age(p.age), name(p.name), ref(p.ref)
{
++(*ref);
}
~People()
{
if(--(*ref) == 0)
{
delete[] name;
delete ref;
}
}
};
int main()
{
People p1("kim", 2);
People p2(p1); // 복사 생성자 호출
}
4. 얕은 복사 해결책 : 복사 금지 (delete copy constructor)
class People
{
private:
char* name;
int age;
public:
People(char* n, int a) : age(a)
{
name = new char[strlen(n)+1];
strcpy(name, n);
}
~People()
{
delete[] name;
}
private:
People(const People& p){} // Private이기에 접근 불가 하여 복사 불가.
// friend 선언하면 접근 가능해지기 떄문에 선언만 만들어야 함. 구현부 없어야 함. - Link error. - 구버전 방식
public:
People(const People& p) = delete; // 신버전 방식. Compile Error.
// 일부 Compiler에서는 private에 접근하여 Error다 라고 말해주는 Compiler가 있어 public에 놓자는 의견도 있음.
};
int main()
{
People p1("kim", 2);
People p2(p1); // 복사 생성자 호출.
// 컴파일 시간 에러가 나오게 하자. 복사 불가로 만듦.
}
5. 얕은 복사 해결책 : using string
class People
{
private:
string name;
int age;
public:
People(string n, int a) : age(a), name(n)
{
}
};
int main()
{
People p1("kim", 2);
People p2(p1); // 복사 생성자 호출.
}
// embedded에서는 C++표준 라이브러리 사용에 대해서 부정적적이면 STL사용 하지 않는 곳도 있음.
'프로그래밍언어 > C++' 카테고리의 다른 글
상수 멤버 함수 (const member function) (0) | 2017.03.19 |
---|---|
정적 멤버 데이터 (static member data) (0) | 2017.03.17 |
복사 생성자 (Copy Constructor) (0) | 2017.03.17 |
initialize list, 초기화 리스트 (0) | 2017.03.17 |
소멸자 (0) | 2017.03.16 |