#include<iostream>
using namespace std;
///////////////////////////////////////////////////////////////////////////////////////////
// 객체의 얕은 복사 이야기
// 1. 생성자에서 자원을 획득할 경우, 소멸자에서 자원을 반납하자! RAII
// RAII : resource acquision is initialize ( 자원을 획득하는 것은 객체의 초기화 이다.)
// 2. 클래스 내부에 포인터 멤버가 있다면 컴파일러가 제공하는 복사 생성자는 얕은 복사 현상을 일으킨다.
// 사용자는 반드시 이문제를 해결해야 한다.
//
// 3. 해결책
// (A) 깊은 복사
// (B) 참조 계수
// (C) 소유권 이전
// (D) 복사 금지
//
///////////////////////////////////////////////////////////////////////////////////////////
/*
class Cat{
char *name;
int age;
public :
Cat (const char *n, int a): age(a){
name = new char[strlen(n)+1];
strcpy(name,n);
}
~Cat (){delete[] name;}
};
int main(){
Cat c1("NABI",2);
Cat c2(c1); //런타임에러 디버그 모드에서.. //포인터만 복사.. 하는경우는?! shallow copy 얕은 복사를 한다.
//이럴때는 소멸자에서 같은 메모리를 두번 지우려고 한다.
}
*/
///////////////// (A) 깊은 복사 /////////////////////////////////////
/*
class Cat{
char *name;
int age;
public :
//깊은 복사를 구현한 복사 생성자
Cat(const Cat & c ): age(c.age) // 1. 포인터가 아닌 멤버는 그냥 복사
{
name = new char[strlen(c.name+1)];
strcpy(name, c.name); // 메모리를 복사
}
Cat (const char *n, int a): age(a){
name = new char[strlen(n)+1];
strcpy(name,n);
}
~Cat (){delete[] name;}
};
int main(){
Cat c1("NABI",2);
Cat c2(c1); //런타임에러 디버그 모드에서.. //포인터만 복사.. 하는경우는?! shallow copy 얕은 복사를 한다.
//이럴때는 소멸자에서 같은 메모리를 두번 지우려고 한다.
}*/
/*
/////////////////////////////////////////////////////////////////////////////////////
////////////////// (B)참조계수법: 메모리를 복사하지말고 카운트를 하자! //////////////////
class Cat{
char *name;
int age;
int *pRef;
public :
// 참조 계수를 기반으로 만들어진 복사 생성자
Cat(const Cat&c) : name (c.name), age(c.age),pRef(c.pRef){
++(*pRef);
}
Cat (const char *n, int a): age(a){
pRef = new int(1); //1개를 1로 초기화
name = new char[strlen(n)+1];
strcpy(name,n);
}
~Cat (){
if(--(*pRef)==0){
delete[] name;
delete pRef;
}
}
};
int main(){
Cat c1("NABI",2);
Cat c2(c1); //런타임에러 디버그 모드에서.. //포인터만 복사.. 하는경우는?! shallow copy 얕은 복사를 한다.
//이럴때는 소멸자에서 같은 메모리를 두번 지우려고 한다.
//c1.name = "AAA"; //이순간 C1 C2는 자원(이름)을 분리해야한다.
//copy on write (COW)라는 기술~
}
*/
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// (C) 소유권이전의 복사생성자 기술1 ////////////////////////////
/*
class Cat{
char *name;
int age;
public :
//swap 같등을 만들때 아주 좋은 방식이다! 차세데 C++ ㅇ는 move 생성자라고 부른다
// 현재는 C++ 표준인 auto_ptr<> 이 이기술을 사용한다
//소유권 이전의 복사 생성자 기술!!
Cat(Cat & c):name(c.name),age(c.age) //얕은 복사
{
c.name=0;
c.age=0;
}
Cat (const char *n, int a): age(a){
name = new char[strlen(n)+1];
strcpy(name,n);
}
~Cat (){delete[] name;}
};
int main(){
Cat c1("NABI",2);
Cat c2(c1); //런타임에러 디버그 모드에서.. //포인터만 복사.. 하는경우는?! shallow copy 얕은 복사를 한다.
//이럴때는 소멸자에서 같은 메모리를 두번 지우려고 한다.
}
*/
/*
//////////////////////////////////(D) 복사금지 기법///////////////////////////////////////
class Cat{
char *name;
int age;
//private 복사 생성자 .. 복사 금지 할떄 사용하는 기술
Cat (const Cat & c); //선언만한다 1.일단선언이 있으므로 컴파일러는 디폴트복사를 제공하지 않는다.
//2.어딘가에서 호출하는 코드가 있으면 구현이 없으므로 링크 에러이다.
// 멤버함수에서도 호출 할 수 없다.
//보통 복사를 금지하면 대입도 금지한다
void operator=(const Cat&);
public :
void foo(){
// Cat c1("A",10);
// Cat c2(c1); //OK 에러를 내게한다.
}
Cat (const char *n, int a): age(a){
name = new char[strlen(n)+1];
strcpy(name,n);
}
~Cat (){delete[] name;}
};
int main(){
Cat c1("NABI",2);
// Cat c2(c1); //캄파일 시간에러가 나오게 하자!
}
//////////////////////////////////////////////////////////////////////////////////////////////
*/
////////////////////////////////////////////////////////////////////////////////
// 복사 연산자는 너무나 유용하기 때문에 따로 클래스를 만들어 사용하는경우가 많다,
//
//////////////////////////////////////////////////////////////////////////
class uncopyable
{
private:
uncopyable(const uncopyable &);
void operator=(const uncopyable &);
};
//이것을 상속 받아 사용하면된다.
class Cat : private uncopyable{
char *name;
int age;
public :
Cat (const char *n, int a): age(a){
name = new char[strlen(n)+1];
strcpy(name,n);
}
~Cat (){delete[] name;}
};
int main(){
Cat c1("NABI",2);
// Cat c2(c1); //캄파일 시간에러가 나오게 하자!
}
///////////////////////////////////////////////////////////////////////////
'C,C++ > Android_FrameWork' 카테고리의 다른 글
[SSM 안드로이드 프레임워크 개발 강의]14-1.스마트 포인터 (0) | 2012.08.14 |
---|---|
[SSM 안드로이드 프레임워크 개발 강의]13.연산자 재정의와 테크닉 (0) | 2012.08.14 |
[SSM 안드로이드 프레임워크 개발 강의]12. 복사생성자 (0) | 2012.08.14 |
[SSM 안드로이드 프레임워크 개발 강의]11. 함수포인터로 구현해본 안드로이드 Thread 예제제 (0) | 2012.08.13 |
[SSM 안드로이드 프레임워크 개발 강의]10. 멤버함수 호출의 정리 (0) | 2012.08.13 |