[C++] 복제 제어 및 스마트 포인터
다음은 드롭 포인터가 발생하는 클래스 인스턴스입니다.
class UnsmartPtr{
public:
UnsmartPtr(int* p, string i):ptr(p),value(i){}
int* get_ptr() const { return ptr;}
string get_i() const { return value;}
void set_ptr(int* p){ ptr=p;}
void set_string(string i){ value=i;}
int get_ptr_value() const { return *ptr;}
void set_ptr_value(int v) const { *ptr=v;}
private:
int* ptr;
string value;
}
드롭 포인터는 다음과 같이 발생합니다.
int* obj=new int(0);
UnsmartPtr up1(obj,"42"); // up1
UnscmartPtr up2(up1); // up1 up2
//up1 up2 ptr *obj, *obj
up1.set_ptr_value(3);
up2.get_ptr_value(); // 3
delete obj; // obj
up1.get_ptr_value(); // ?
up2.set_ptr_value(4); // ,
복제는 값 전달 행위를 대표하고 바늘은 주소 전달 행위를 대표하기 때문에 일반적으로 바늘 구성원이 있는 유형에 대해 서로 다른 복제 전략을 통해 바늘 구성원에게 서로 다른 행위를 일으키고 어느 정도에 잠재적인 현수 바늘 문제를 해결할 수 있다.일반적인 유형의 실현에는 두 가지 방법이 있는데 하나는 스마트 지침을 사용하여 지향된 대상의 삭제를 제어하는 것이다.두 번째는 모든 포인터가 가리키는 대상을 유일하게 복제하는 것이다.
복제 행위의 유형을 사용하면 대량의 실례화를 할 때 대량의 메모리를 소모하여 원래 공유할 수 있는 데이터를 저장한다. 비록 지침을 드리우는 문제가 해결되었지만 메모리의 사용에 있어서는 사치스럽다.그러므로 일반적으로 스마트 지침류를 이용하여 공유의 대상을 제어한다.스마트 포인터류는 사실 신비로운 것이 없다. 단지 스마트 포인터류는 포인터 구성원의 구축과 소각에 대해 하나의 계수 과정을 가진다. 이 과정은 포인터를 삭제할 때 포인터가 가리키는 대상의 삭제 여부를 제어하고 가리키는 공유 대상이 마지막에 완전히 사용하지 않을 때 방출된다.
지능 지침은 두 가지 실현 방법이 있는데 하나는 계수류를 사용하는 것이고, 다른 하나는 핸들류를 사용하는 것이다.다음은 계수 클래스를 구현하는 방법입니다.
4
//
class S_Ptr{
firend class SmartPtr;
int* ip;
size_t use;
S_Ptr(int* p):ip(p),use(1){}
~S_Ptr(){ delete ip;}
}
//
class SmartPtr{
public:
SmartPtr(int* p, string v):ptr(new S_Ptr(p)),value(v){}
SmartPtr(const SmartPtr& ori):ptr(ori.ptr),value(ori.value){ ++ptr->use;}
SmartPtr& operator=(cosnt SmartPtr&);
~SmartPtr(){ if(--ptr->use==0) delete ptr;}
private:
S_Ptr* ptr;
string value;
}
use멤버는 ptr바늘멤버의 방출 여부를 제어할 수 있음을 실례로 잘 알고 있다.핸들 클래스는 계수 클래스에 비해 보다 직관적입니다.
4
class HandlePtr{
public:
HandlePtr():p(0),use(new std::size_t(1)){}
HandlePtr(const Obj&);
HandlePtr(const HandlePtr& i):p(i.p),use(i.use){++*use;} // ,
~HandlePtr(){ decur_use();}
HandlePtr& operator=(const HandlePtr&);
const Obj* operator->() const { if(p) return p;
else throw std::logic_error();}
const Obj& operator*() const { if (p) return *p;
else throw std::logic_error();}
private:
Obj* p;
std::size_t* use; //
void decr_use(){ if(--*use==0){ delete p; delete use;}}
}
HandlePtr& operator=(const HandlePtr& rhs){
++*rhs.use; //
decr_use(); // , ,
p=rhs.p;
use=rhs.use;
return *this;
}
포인터 구성원이 있는 대상은 일반적으로 복제 제어 구성원을 정의해야 한다. 포인터 구성원이 이 대상을 가리키면 구성원이 가리키는 대상이 반드시 존재해야 한다.바늘 구성원을 관리하기 위해서는 복제 제어 구성원 세 개를 정의해야 한다. 복제 구조 함수, 할당 조작 함수와 분석 함수이다.복제 구조 함수와 값 부여 조작 함수는 지향된 대상의 사용을 정확하게 계수할 수 있어야 하고 분석은 지침 구성원에 대한 제어를 필요로 하며 마지막 순간에 지향된 대상을 소각할 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Rust의 참조, Box, Rc가 함수인 매개변수, 값을 반환할 때의 동작적절한 구조체를 만들어 해당 구조나 Box가 함수로 지정된 매개변수 또는 값을 반환할 때의 동작을 확인합니다. 주소 확인을 위해 i32를 가진 멤버Obj와 실현Copy TRAITObjCp를 준비했다. 납품 가격 실행...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.