C++스마트 포인터 의 시 뮬 레이 션 구현 인 스 턴 스
1.도입
int main()
{
int *p = new int; //
delete p;
return 0;
}
위의 코드 에서 누 드 포인터 p 를 정 의 했 습 니 다.수 동 으로 풀 어야 합 니 다.만약 우리 가 조심 하지 않 아 이 지침 을 놓 는 것 을 잊 거나 이 지침 을 놓 기 전에 약간의 이상 이 발생 하면 심각 한 결 과 를 초래 할 수 있다(메모리 유출).스마트 포인터 도 이런 문 제 를 해결 하고 프로그래머 들 이 포인터 사용 에 전념 하여 메모리 관 리 를 스마트 포인터 에 게 맡 기 는 데 주력 하고 있다.보통 지침 에 도 지침 이 걸 리 기 쉬 워 요.여러 개의 지침 이 같은 대상 을 가리 킬 때 어떤 지침 이 이 대상 을 delete 했 기 때문에 이 지침 은 이 대상 을 조작 하지 않 습 니 다.그러면 다른 대상 을 가리 키 는 지침 은 요?삭 제 된 기본 대상 을 기다 리 고 있 으 며 언제든지 조작 할 준비 가 되 어 있 습 니 다.그래서 현수 포인터 가 형성 되 었 고 프로그램 이 무 너 질 날 도 멀 지 않 았 다.
int main()
{
int *p1 = new int(2);
int *p2 = p1;
int *p3 = p2;
cout<<*p1<<endl;
cout<<*p2<<endl;
cout<<*p3<<endl;
delete p1;
cout<<*p2<<endl;
return 0;
}
출력 결과
2
2
2
-572662307
출력 결과*p2 의 결 과 는 기대 중 2 가 아 닙 니 다.2 가 이미 삭제 되 었 기 때 문 입 니 다.지능 포인터
지능 지침 은 일반 지침 을 봉 하여 일반 지침 과 같은 기능 을 실현 할 수 있 는 유형 이다.다른 것 은 스마트 포인터 가 메모 리 를 자동 으로 관리 할 수 있 고 클래스 대상 을 이용 하여 역할 도 메 인 을 호출 하여 포인터 에 대한 방출 을 분석 함수 에 적어 서 포인터 가 걸 리 는 상황 이 발생 하지 않도록 하 는 것 이다.
스마트 포인터(smart pointer)는 동적 분배(더미)대상 을 가리 키 는 지침 을 저장 하 는 클래스 로 생존 기 제어 에 사용 되 며 동적 분배 대상 을 자동 으로 정확하게 소각 하여 메모리 유출 을 방지 할 수 있다.그것 의 일반적인 실현 기술 은 인용 계수(reference count)를 사용 하 는 것 이다.스마트 포인터 류 는 하나의 계수 기 를 클래스 가 가리 키 는 대상 과 연결 시 키 고 이 클래스 가 몇 개의 대상 이 같은 지침 을 공유 하 는 지 를 참조 하여 추적 합 니 다.클래스 의 새 대상 을 만 들 때마다 포인터 를 초기 화하 고 인용 수 를 1 로 설정 합 니 다.대상 이 다른 대상 의 복사 본 으로 만 들 때 구조 함수 복사 지침 을 복사 하고 이에 상응하는 인용 수 를 증가 합 니 다.한 대상 에 게 할당 을 할 때 할당 연산 자 는 왼쪽 연산 자가 가리 키 는 대상 의 인용 수 를 줄 이 고(인용 계수 가 0 으로 줄 어 들 면 대상 을 삭제 합 니 다)오른쪽 연산 자가 가리 키 는 대상 의 인용 수 를 증가 합 니 다.석조 함 수 를 호출 할 때 구조 함 수 는 인용 계 수 를 줄 입 니 다(인용 계수 가 0 으로 줄 어 들 면 기본 대상 을 삭제 합 니 다).
지능 지침 은 지침 동작 을 모 의 하 는 유형 이다.모든 스마트 포인터 가 다시 불 러 옵 니 다.->와*연산 자 입 니 다.지능 지침 에는 또 많은 다른 기능 이 있 는데,비교적 유용 한 것 은 자동 소각 이다.이것 은 주로 창고 대상 의 유한 작용 역 과 임시 대상(유한 작용 역 실현)분석 함 수 를 이용 하여 메모 리 를 방출 한다.물론 스마트 포인 터 는 이 뿐만 이 아니 라 복사 시 원본 대상 을 수정 할 수 있 는 등 도 포함 된다.스마트 포인터 가 수요 에 따라 디자인 도 다르다.auto_ptr 는 흔히 볼 수 있 는 스마트 지침 이다.
지능 포인터 의 실현(클래스 템 플 릿 으로 구현)
class Test
{
public:
Test()
{
cout<<"Test()"<<endl;
}
~Test()
{
cout<<"~Test()"<<endl;
}
void func()
{
cout<<"call Test::func()"<<endl;
}
};
template<typename T>
class CSmartptr
{
public:
CSmartptr(T *ptr):_ptr(ptr)
{cout<<"CSmartptr()"<<endl;}
CSmartptr(const CSmartptr<T> &other)
{
_ptr = new T;
*ptr = *other._ptr;
}
~CSmartptr()
{
cout<<"~CSmartptr()"<<endl;
delete _ptr;
}
void relase() const
{
((CSmartptr<T> *)this)->owns = false;
}
T& operator*()
{
return *_ptr;
}
const T& operator*()const {return *_ptr;}
T *operator->()
{
return _ptr;
}
const T *operator->()const {return _ptr;}
private:
T *_ptr;
};
int main()
{
CSmartptr<int> p1(new int);
*p1 = 200;
CSmartptr<Test> p2(new Test);
p2->func();
return 0;
}
아 날로 그 실현 autoptr
template<typename T>
class CSmartptr
{
public:
CSmartptr(T *ptr):_ptr(ptr),owns(true){cout<<"CSmartptr()"<<endl;}
CSmartptr(const CSmartptr<T> &other)
{
other.relase();
_ptr = other._ptr;
}
~CSmartptr()
{
cout<<"~CSmartptr()"<<endl;
if( owns == true)
{
cout<<"~CSmartptr()"<<endl;
delete _ptr;
}
}
void relase() const
{
((CSmartptr<T> *)this)->owns = false;
}
T& operator*()
{
return *_ptr;
}
const T& operator*()const {return *_ptr;}
T *operator->()
{
return _ptr;
}
const T *operator->()const {return _ptr;}
private:
T *_ptr;
bool owns; // ,
};
int main()
{
CSmartptr<int> p1(new int);
*p1 = 200;
CSmartptr<Test> p2(new Test);
p2->func();
return 0;
}
인용 계수 가 있 는 스마트 포인터(자원 관리 와 방출 에 편리 함)
class CHeapTable
{
public:
static CHeapTable& getInstance()
{
return mHeapTable;
}
//
void addRef(void *ptr)
{
pthread_mutex_lock(mutex);
list<Node>::iterator it = find(mList.begin(),
mList.end(), ptr); // Node == Node it->mpaddr
if(it == mList.end())
{
mList.push_front(ptr);
cout<<"new addr:"<<ptr<<" ref:"<<1<<endl;
}
else
{
it->mcount++;
cout<<"add addr:"<<ptr<<" ref:"<<it->mcount<<endl;
}
pthread_mutex_unlock(mutex);
}
//
void delRef(void *ptr)
{
list<Node>::iterator it = find(mList.begin(),
mList.end(), ptr);
if(it != mList.end())
{
it->mcount--;
cout<<"del addr:"<<ptr<<" ref:"<<it->mcount<<endl;
if(it->mcount == 0)
{
mList.erase(it);
}
}
}
//
int getRef(void *ptr)
{
list<Node>::iterator it = find(mList.begin(),
mList.end(), ptr);
if(it != mList.end())
{
return it->mcount;
}
return 0;
}
private:
CHeapTable(){}
static CHeapTable mHeapTable;
struct Node
{
Node(void *ptr=NULL):mpaddr(ptr),mcount(1){}
bool operator==(const Node &src)
{
return mpaddr == src.mpaddr;
}
void *mpaddr; //
int mcount; //
};
list<Node> mList;
};
CHeapTable CHeapTable::mHeapTable;
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr = NULL)
:mptr(ptr)
{
if(mptr != NULL)
{
addRef();
}
}
~CSmartPtr()
{
delRef();
if(0 == getRef())
{
delete mptr;
mptr = NULL;
}
}
CSmartPtr(const CSmartPtr<T> &src)
:mptr(src.mptr)
{
if(mptr != NULL)
{
addRef();
}
}
CSmartPtr<T>& operator=(const CSmartPtr<T> &src)
{
if(this == &src)
return *this;
delRef();
if(0 == getRef())
{
delete mptr;
mptr = NULL;
}
mptr = src.mptr;
if(mptr != NULL)
{
addRef();
}
}
T& operator*(){return *mptr;}
const T& operator*()const{return *mptr;}
T* operator->(){return mptr;}
const T* operator->()const{return mptr;}
void addRef(){mHeapTable.addRef(mptr);}
void delRef(){mHeapTable.delRef(mptr);}
int getRef(){return mHeapTable.getRef(mptr);}
private:
T *mptr;
static CHeapTable &mHeapTable;
};
template<typename T>
CHeapTable& CSmartPtr<T>::mHeapTable = CHeapTable::getInstance();
이상 은 바로 스마트 포인터 의 사례 상세 한 설명 입 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남기 거나 본 사이트 지역사회 에 가서 토론 을 하 십시오.읽 어 주 셔 서 감사합니다. 도움 이 되 셨 으 면 좋 겠 습 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C 언어 포인터를 이해하는 간단한 예 ~ 누구나 알 수있는 포인터의 장점 ~값 및 참조 정보 함수 인수 정보 인스턴스 정보 포인터가 없는 경우와 있는 경우의 샘플 코드 요약 메모리의 데이터는 주소 -> 1000 ~ 1003 값 -> 메모리 내용 이 두 가지로 구성된 이미지입니다. 주소를 참...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.