2012. 8. 15. 11:04

#include<iostream>

#include"memchk.h"

using namespace std;


//new를 재정의하는 다양한 기법



int main(){

int *p1 = new int;

int *p2 = new int;

int *p3 = new int;

delete p2;

/*


cout << __FILE__ << endl;

cout << __LINE__ << endl;

cout << __TIME__ << endl;

*/ //표준 C/C++ 에서 지원하는 메크로


return 0; // 다른 헤더에서 메임을 가짜로 바꿨으니.. 리턴0을 써줘야한다

}

====================================memchk.h==============================================


#include<iostream>

using namespace std;


struct MEM{


char file[256];

int line;

void * addr;

};


MEM mem[1000];

int count =0;

void * operator new (size_t sz , char *file , int line){

void *p = malloc(sz);

//할당정보를 배열에 보관한다.


mem[count].addr = p;

mem[count].line = line;

strcpy(mem[count].file, file);

++count;

return p;

}


void operator delete(void *p){


for(int i=0;i<count ; i++){

if(mem[i].addr ==p){

mem[i] = mem[count-1];

free(p);

--count;

break;

}

}

}

int Main();

int main(){

int ret = Main();  //사용자 메인함수는 단순 호출이고 그뒤에 내가 원하는 결과를 붙인다.


if(count == 0)cout << "메모리 누수가 없습니다"<<endl;

else{

cout << count << "개의 메모리 누수가 있습니다."<<endl;

for(int i=0;i<count;i++){

printf("%s(%d):%p\n",mem[i].file, mem[i].line, mem[i].addr);

}

}

return ret;

}


#define main Main   //이후에 메인은 메인이 아니다!!!  그 메인의 리턴값 이후에 무언가를 출력시킴 

#define new new(__FILE__, __LINE__)  //new를 디파인

int *p = new int;


Posted by k1rha
2012. 8. 15. 11:02

#include<iostream>


using namespace std;


/////////////////////////////////////////////////

//New 이야기

//1 New 의 동작 방식

//(A)operator new() 함수를 사용해서 메모리를 할당 한후

//(B)(A) 가 성공했고 객체 였다면 생성자 호출

//(C) 주소를 해당 타입으로 캐스팅해서 리턴.

//

//delete

//(A) 소멸자 호출

//(B) operator delete()를 사용해서 메모리 해지

//

//////////////////////////////////////////////////////////////////

class Test{


public:

Test(){cout<<"Test()"<<endl;}

~Test(){cout<<"~Test()"<<endl;}

};


int main(){

//생성자 소ㅕㄹ자의 호출없이 메모리만 할당/해지하는 방법

//결국 C의 malloc과 유사


Test *p = static_cast<Test *>(operator new( sizeof(Test));

operator delete(p);


}

=====================================================================================


Posted by k1rha
2012. 8. 14. 17:43

#include<iostream>

using namespace std;


/////////////////////////////////////////////////////////////

// 변환 이야기

// Point -> int : 변환 연산자

// int -> Point : qusghks todtjdwk (인자가 1개인 생성자)

////////////////////////////////////////////////////////////


class Point{



int x, y;


public:

Point() :x(0),y(0){}

Point(int a , int b):x(a),y(b){}


//변환 연산자 : 객체를 다른 타입으로 암시적/ 명시적 형변환 되게 한다.

// 변환 연산자는 리턴값을 표시하면 에러이다.

operator int(){


return x;

}


Point(int a) :x(0),y(0){} // 변환생성자 

};

/*

int main(){


double d = 3.4;

int n =d;


Point p(1,2);

int n2 = p; //p.operator int() 가 있으면 된다.

}

*/


int main(){

Point p1(1,2);

int n =p1; // p1.operator int() 이므로 OK 

//Point -> int 변환

// p1=n; // int -> Point 변환 

// 똑같은 의미에서 n.operator Point() 가 있으면 된다. 하지만 n 은 객체가 아니다 ㅠㅠ


p1=n; // 변환 생성자 적용 후 int 형생성자가 있으면 가능하다!

//컴파일러가 임시 객체를 만들어서 집어넣은뒤 대입연산자를 통해 넣어주게 된다.

}



================================ 활용 법 ===========================================


#include<iostream>

using namespace std;


class OFile 

{


FILE *file;


public:


//모르는 연산자가 넘어오는 것을 방지하기 위해서.. 인자가 1개인 생성자가 암시적으로 변환을 일으키는 것을 막는다.

//explicit  // 단! 명시적 변환은 된다.

explicit OFile (const char *name , const char *mode = "wt"){

file = fopen (name ,mode);

}

~OFile(){fclose(file);}


void write(const char *s){fwrite(s,1,strlen(s),file);}


//operator  // 차세대 C++ 은 변환  연산자 앞에도 explocit 를 붙일 수 있따.

operator FILE*(){return file;} // 변환 연산자?!!!


};


/////////////////////////////////////////////////////////////////////

//변환 연산자의 적절한 예시

////////////////////////////////////////////////////////////////////

/*

int main(){

OFile f("a.txt");

f.write("hellow");

int n=10;

fprintf(f,"n=%d",n); //OFILE 이 파일포인터로 변환만 될수 있따면 ..ㅠㅠ 벼..변환 연산자?!

///////////////변환 연산자 후엔 다 슬수 있다.////////////////////

fputs("world",f);



////////////////다른 예를 들어보자! ////////////////////////////////////////////

// char s[10]="hello";

// String s2="aaa";

// strcpy(s,s2); //?



}


*/

void foo(OFile f){


}

int main(){


OFile f("a.txt");

foo(f); // 당연하다!!!! 

//////////////explicit 적용전 ///////////////////////

/// foo("hellow"); //!?

//error 가 나와야한다

//잘된다!! char * -> OFile 이 면 된다! 

//////////explicit 적용후는 안됨 ///////////////////////


foo((OFile)"hellow"); //의도적으론 된다.

}

==================================================================================================

Posted by k1rha
2012. 8. 14. 16:52

#include<iostream>

#include<algorithm>


using namespace std;


///////////////////////////////////////////////////////////////////////////////

// STL 의 sort() 는 마지막 인자가 T로 되어 있다.

//

//

//

///////////////////////////////////////////////////////////////////////////////


// 아래 코드의 단점 인라인 처리가 안된다?!

/*

int cmp1(int a, int b) {return a-b;}

int cmp2(int a, int b) {return b-a;}


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

sort(x,x+10,cmp1);  //sort(int *, int *, int(*)(int,int)) 함수 생성 

sort(x,x+10,cmp2); //sort(int *, int*, int(*)(int,int))




}

*/


//////////////////////////////////////////////////////////////////////////////

// 이미 있는 STL 이다!!

// #include <functional> 다있다! 다있따!  //less<> , greater<>

////////////////////////////////////////////////////////////////////////////

template<typename T>struct less{

bool operator()(T a,T b){return a<b;}

};


struct greater {bool operator()(int a, int b){return a>b;}};


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

less<int> cmp1;

greater cmp2;


sort(x,x+10,cmp1); //sort(int *, int *, less) 함수 생성

sort(x,x+10,cmp2); //sort(int *, int*, greater) 함수 생성




}

=====================================================================

함수객체이야기

=====================================================================

#include<iostream>

#include<algorithm>


using namespace std;


///////////////////////////////////////////////////////////////////////////////

// STL 의 sort() 는 마지막 인자가 T로 되어 있다.

//

//

//

///////////////////////////////////////////////////////////////////////////////


// 아래 코드의 단점 인라인 처리가 안된다?!

/*

int cmp1(int a, int b) {return a-b;}

int cmp2(int a, int b) {return b-a;}


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

sort(x,x+10,cmp1);  //sort(int *, int *, int(*)(int,int)) 함수 생성 

sort(x,x+10,cmp2); //sort(int *, int*, int(*)(int,int))




}

*/


//////////////////////////////////////////////////////////////////////////////

// 이미 있는 STL 이다!!

// #include <functional> 다있다! 다있따!  //less<> , greater<>

////////////////////////////////////////////////////////////////////////////

template<typename T>struct less{

bool operator()(T a,T b){return a<b;}

};


struct greater {bool operator()(int a, int b){return a>b;}};


int main(){


int x[10] = {1,2,3,4,5,6,7,8,9,10};

less<int> cmp1;

greater cmp2;


sort(x,x+10,cmp1); //sort(int *, int *, less) 함수 생성

sort(x,x+10,cmp2); //sort(int *, int*, greater) 함수 생성




}


/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////

//절대값 오름 차순시?

/////////////////////////////////////////////////////////////

template <typename T>struct absLess{

inline bool operator()(T a, T b){return abs(a) < abs(b);}


};


int main(){


int x[10] = {1,3,5,7,9,-2,4,6,8,10};

//절대값 오른차순으로 소트하고싶다.

absLess<int> cmp;

sort(x,x+10,cmp);

}

Posted by k1rha
2012. 8. 14. 15:13

#include<iostream>

using namespace std;

/////////////////////////////////////////////////////////////////////////////////

//STL 알고리즘

//guswo C++ 의 대부분의 라이브러리는 Ferneric 을 중요시 합니다 (STL 안드로이드 등) 

//

// Generic 이란 무엇인지 생각해 봅시다

//

// 1. 알고리즘 만들기

//

///////////////////////////////////////////////////////////////////////////////////


/*

//1단계 strchr() 의구현

//검색구간 : NULL 로 끝나는 문자열, ㅜㅕㅣㅣdms rjatordp vhgka dksehlsek.

//구간의 표현 : 포인터 

//구간의 이동 : 전위형 ++

//실패의 전달 : 0(NULL 포인터 )

//


char * xstrchr(char *s,char c){

while( *s !=0 && *s!=c)

++s;


return *s ==0 ? 0 : s;

}


int main(){



char s[] = "abcdefg";

char *p = xstrchr(s,'c');

cout << *p <<endl;

}



*/


/*

//////////////////////////////////////////////////////////////////////////////

//2단계 구현  일반화 - 부분 문자열도 검색이 가능하게 만드는 방법

// 검색 구간 : [fist , last) 사이의 문자열, ㅣㅁㄴㅅ sms rjatordp vhgkadksehla

// 구간의 표현 : 포인터

// 구간의 이동 : 전위형 ++

// 실패의 전달 : 0 (NULL)

//////////////////////////////////////////////////////////////////////////////

char * xstrchr(char *first, char *last , char value){

while(first !=last && *first !=value)++first;

return first == last ? 0 : first;

}

int main(){


char s[] ="abcedfg";

char * p = xstrchr(s,s+5,'c');

cout<< *p <<endl;


}

*/


/*

//////////////////////////////////////////////////////////////////////////////

//2단계 template 이용하기

//문제점 : 1 . 검색 구간의 타입과 검색 대상의 타입이 연관되어 있다.

//해결책 :  double 에 배열에서 int를 검색할 수 없다. 구간의 타입과 검색의 타입을 분리하자!

//

//문제점 : 2. T* 라고 하면 구간은 반드시 진짜 포인터로만 표현 되어야 한다.

//     스마트 포인터를 사용 할 수 없다.

//

/////////////////////////////////////////////////////////////////////////////

template <typename T> T* xfind(T *first, T* last , T value){

while(first !=last && *first !=value)++first;

return first == last ? 0 : first;

}


int main(){


double x[10] = {1,2,3,4,5,6,7,8,9};

double *p = xfind(x, x+10,5.0);

cout << *p << endl;



}

*/


////////////////////////////////////////////////////////////////////////////////

/// 검색내용과 검색부분을 분리해내자! 그렇게되면 스마트 포인터도 사용 할 수있다.

// 검색 구간 : [first, last) 모든 타입의 배열의 부분구간

// 구간의 표현 : 포인터 , 스마트 포인터(단  == , != , * , ++ 4개의 연산자 지원이 되느 스마트 포인터여야 한다.

//

//////////////////////////////////////////////////////////////////////////////

//

//실패의 전달 : last (past the end 라고 부르기도 한다. 마지막검색 다음 요소 

//////////////////////////////////////////////////////////////////////////////////////////////

//

// 이..이것슨!! STL 의 find() 알고리즘이다!!! 

//

///////////////////////////////////////////////////////////////////////////////////////////

template<typename T1, typename T2> T1 xfind(T1 first, T1 last, T2 value){


while(first !=last && *first !=value)++first;

return first;

}


int main(){


double x[10] = {1,2,3,4,5,6,7,8,9};

double *p = xfind(x, x+10,5.0);

cout << *p << endl;


}

Posted by k1rha
2012. 8. 14. 13:59

#include<iostream>

using namespace std;


/*

class Car{


int mCount;

public :

Car() : mCount(0){}


void incStrong(){--mCount;}

void decStrong(){

if(--mCount ==0)delete this;

}

~Car(){cout<<"Car 파괴 "<<endl;}


};

*/


////////////////////////////////////////////////////////////////////////////////////////

/// 안드로이드 프레임웤에서는 모든 클래스가 RefBase 클래스를 상속받아 사용되게 되어있다.

////////////////////////////////////////////////////////////////////////////////////////

class RefBase{


int mCount;

public :

RefBase() : mCount(0){}


void incStrong(){++mCount;}

void decStrong(){

if(--mCount ==0)delete this;

}

virtual ~RefBase(){cout<<"Red 파괴 "<<endl;}


};


class Car : public RefBase{



}

template<typename T> class sp

{

T * m_ptr;

public:

sp(T *other =0):m_ptr(other) {if(m_ptr)m_ptr->incStrong();}

sp(const sp &p):m_ptr(p.m_ptr) {if(m_ptr)m_ptr->incStrong();}

~sp() {if(m_ptr)m_ptr->decStrong();}


T *operator->(){return m_ptr;}

t& operator *(){return *m_ptr;}


}

int main(){


sp<Car> p1 = new Car;

sp<Car> p2=p1;


/*

Car *p1 = new Car;

p1->incStrong(); //객체 생성후 무조껀 1을 증가하자


Car *p2 = p1;

p2->incStrong(); //복사후 1을 증가하자


p1->decStrong(); //3. 모든 포인터는 사용후 1감소하자.

p2->incStrong();

*/

}

Posted by k1rha
2012. 8. 14. 13:58

#include<iostream>

using namespace std;


//1. template 로 만들게 된다!! 당근이징 

//2. 얕은 복사를 해결 해야 한다.

//  (A) 깊은 복사

//  (B) 참조 계수

//  (C) 소유권 이전

//  (D) 복사금지 



/*

template <typename T>class ptr{

T *obj;


public:

ptr(T *p=0):obj(p){}

T *operator->(){return obj;}

T& operator*() {return *obj ;}


~ptr(){delete obj;}

};

//


int main(){

ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;



}

*/

/*

////////////////////////// 복사 금지 ///////////////////////////////

// boost 의 scoped_ptr<> 이 이정책을 사용한다.

//장점 : 가볍다.

//단점 : 단지 자원곤리만 책임지고 대입 , 복사등이 불가능하다.

////////////////////////////////////////////////////////////////////


template <typename T>class scoped_ptr{

T *obj;

scoped_ptr(const scoped_ptr &p);

void operator = (const scoped_ptr &p);


public:

scoped_ptr(T *p=0):obj(p){}

T *operator->(){return obj;}

T& operator*() {return *obj ;}


~scoped_ptr(){delete obj;}

};


//void foo(scoped_ptr<int> p2); //불편함




int main(){

scoped_ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;


//ptr<int> p2= p1; /// 컴파일 에러!! 절대 이렇게는 사용하지 마시요~ 라는 뜻 

}


*/

/*

//////////////////////////////////////// 소유권 이전 ///////////////////////////////

//#include<memory> // 이안에 auto_ptr 이 있다!!

//

/////////////////////////////////////////////////////////////////////////////////////

template <typename T>class Auto_ptr{

T *obj;


public:

//소유권 이전의 전략

Auto_ptr(ptr & p): obj(p.obj){

p.obj=0;

}


Auto_ptr(T *p=0):obj(p){}

T *operator->(){return obj;}

T& operator*() {return *obj ;}


~Auto_ptr(){delete obj;}

};


//void foo(scoped_ptr<int> p2); //불편함




int main(){

Auto_ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;


Auto_ptr<int> p2= p1; //이제 자원은 p2만 사용한다 (소유권 이전)

//cout << * p1 < endl;//error

cout << *p2<<endl; // ok



}

*/

/////////////////////////////////// 참조 계수 /////////////////////////////////////

// boost 에서 만들고 STL 에 새롭게 추가된 shared_ptr 입니다.

/////////////////////////////////////////////////////////////////////////////////////

template <typename T>class Auto_ptr{

T *obj;

int *pRef;


public:

//참조계수 전략


Auto_ptr(T *p=0):obj(p){

pRef = new int(1);


}

ptr(const ptr &p):obj(p.obj),pRef(p.pRef){

++(*pRef);

}


T *operator->(){return obj;}

T& operator*() {return *obj ;}

~Auto_ptr(){

if(--(*pRef)==0){

dlete obj;

delete pRef;

}

}

};


//void foo(scoped_ptr<int> p2); //불편함




int main(){

Auto_ptr<int> p1 = new int;

*p1 = 10;

cout << *p1 << endl;


Auto_ptr<int> p2= p1; //이제 자원은 p2만 사용한다 (소유권 이전)

//cout << * p1 < endl;//error

cout << *p2<<endl; // ok



}

Posted by k1rha
2012. 8. 14. 13:57

#include<iostream>

using namespace std;


//////////////////////////////////////////////////////////////////////////////

// 스마트 포인터 : 임의의 객체가 다른 타입의 포인터 처럼 사용되는것

// 장점 : 진짜 포인터가 아니라 객체이다. 생성 복사 대입 소멸 모든과정을

// 사용자가 제어 할 수 있다. 대표적인 예가 소멸자에서의 자동 삭제 기능! 

//

//3. 주로 ->, * 연산자를 재정의해서 만들게 된다.


////////////////////////////////////////////////////////////////////////////


class Car

{

public:

void Go(){cout<<"car go"<<endl;}


};

//스마트 포인터 : 임의의 객체가 다른 타입의 포인터 처럼 사용되는 것.

class ptr{

Car *obj;

public:

ptr(Car *p=0):obj(p){}

Car *operator->(){return obj;}

Car& operator*() {return *obj ;}


~ptr(){delete obj;}

};


int main(){

ptr p=new Car;

p->Go(); // (p.operator->())Go() 이지만 

// (p.operator->())->Go() 처럼 해석된다.


/*

Car *p = new Car;

p->Go();

delete p;

*/


}

===================================================================================


Posted by k1rha
2012. 8. 14. 11:51

#include<iostream>

using namespace std;


//연산자 재정의 개념

//철학 : 사용자 정의 타입도 빌트인 타입처럼 동작해야한다.

// 단축 표기의 미학!!

//1. + 도 결국 함수로 표현된다. operator +

//2. p1+p2 는 operator+(p1,p2)



///////////////////////////////// Friend 로 구성한 operator+//////////////////////////////////

/*

class Point{

int x,y;


public : 

Point(int a = 0, int b= 0) : x(a),y(b){}

//멤버변수가 아니더라도 private 에 접근 할수 있게 해달라.

friend Point operator+(const Point & p1, const Point &p2);

};

Point operator+(const Point &p1, const Point &p2){

return Point(p1.x +p2.x,p1.y+p2.y);

}

int main(){


Point p1(1,1);

Point p2(2,2);

Point p3= p1+p2; // operator+(p1,p2)가 있으면 된다.

//p1.operator+(p2) 라고 해석하기도 한다.


Point p4 = p1+5;

Point p5 = 5 +p1;

}

*/


///////////////////////멤버로 구성한 operator+ /////////////////////////////////


class Point{

int x,y;


public : 

Point(int a = 0, int b= 0) : x(a),y(b){}

//멤버변수가 아니더라도 private 에 접근 할수 있게 해달라.

Point operator+(const Point &p){

return Point (x + p.x, y + p.y);

}

};


int main(){


Point p1(1,1);

Point p2(2,2);

Point p3= p1+p2; // operator+(p1,p2)가 있으면 된다.

//p1.operator+(p2) 라고 해석하기도 한다.



Point p4 = p1+5;


//Point p5 = 5+p1;  //에러가 뜬다? why? 다음시간에 배움

}

//0. -,(),[],-> : 반드시 멤버여야 한다.

//1. 단항 : 멤버가 좋다

//2. 이항중 : += , -= , *= 등은 멤버가 좋다.

//3. 2를 제외한 이항 : 전역이 좋다.

//

//철학은 객체의 상태가 변경되면 멤버가 좋다!! ++a; a+=b; a+b;




=========================================================================================



#include<stdio.h>




//cout 의 원리


class ostream{


public :

ostream& operator<<(int n) {printf("%d",n);return *this;}

ostream& operator<<(const char *s ) {printf("%s",s);return *this;}

ostream& operator<<(ostream &(*f)(ostream &)){

f(*this);

return *this;

}

};

ostream cout;

ostream& end (ostream& os){

os<<"\n";

return os;

}

ostream& tab (ostream& os){

os<<"\t";

return os;

}


int main(){


int n =10;


cout<< n <<tab <<end; //cout.operator <<(n)

cout << "hello"; //cout.operator <<("hello")


}



Posted by k1rha
2012. 8. 14. 10:38

#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); //캄파일 시간에러가 나오게 하자! 



}

///////////////////////////////////////////////////////////////////////////


Posted by k1rha