스마트 포인터의 소스 코드 분석 atuo_ptr

의 C ++은 가비지 콜렉션, 힙 메모리가 수동으로 만 열 수 있습니다처럼 수동 방출 시스템은 스택, 시스템 릴리스처럼 열 수 있습니다, 그래서 메모리를 수동으로 열 구현하는 스마트 포인터의 출현이 없기 때문에, 시스템은 메모리 누수를 방지 해제 ;

우리는 당신이 다음 바인딩 메모리의 무리와 함께 스택 객체를 고려하고 소멸자에서 힙 메모리를 해제 할 수 있도록 그 범위를 떠나 스택 객체, 소멸자가 자동으로 호출되는 것을 알 수 객체가 스택 범위를 벗어나면, 힙 메모리 자동 스마트 포인터의 원리 (본질적 스택 객체) 인 방출된다. 이 주제처럼 시도하고 스택 포인터처럼 보이는, 그래서 우리는 사실, 그냥 일반적인 스택은 객체이고, 스마트 포인터를 호출합니다. 

C ++ 98 만 자동 PTR,이 포인터는 지금은 거의 포기 된, 불완전하지만, 우리는 여전히 그것을 포기해야하는 이유를 이해 그가 무슨 생각을 이해해야합니까? 그리고 그가 얼마나 어떻게 C ++ 11 그것을 개선하기 위해?

자동 auto_ptr은 즉 // 포인터 포인터가 자동으로 포인터를 사용할 수있는 권리 양도 scoped_ptr를 다른
, 원래 auto_ptr은 포인터 튜브의 소유권을 잃게 할당 또는 복사를 수행 한 후 // 구성을, 그 포인터가 형성 NULL입니다
/ 건설 복사 할당 후 / 한편, 포인터가 NULL 가리 킵니다 원래 auto_ptr은, 또한 가장 큰 단점 중 하나입니다;

사용법 #include <iostream>
은 Using 네임 스페이스 STD;


// 간단한
클래스 A
{
: 공공
무효 재미 ()
{

}
}


템플릿 <클래스 T>

// 클래스 템플릿
클래스 auto_ptr은
{
: 공공

// 생성자 명시 적으로 금지 형 변환
명시 auto_ptr은 (T * P = 0) 드로우 ()
(! P = 0) m_bIsOwner, m_ptr (P)
{
COUT << "DEBUG1"<< ENDL;
}

// 오너 전송
auto_ptr은 (CONST auto_ptr은 <T> & Y) 드로 ()
: m_bIsOwner (y.m_bIsOwner) m_ptr (y.release ())
{
COUT << "debug2"<< ENDL;
}

// 오너 전송
auto_ptr은 <T> = & 연산자 ( CONST auto_ptr은 <T> &Y) 드로우 ()
{
<< COUT "debug3"<< ENDL;

IF (! =이 본 Y) Y // 현재 오브젝트는 오브젝트가 아닌
{
COUT << "debug4"<< ENDL;

IF (! = m_ptr y.get ()) // 현재 개체 Y 어드레스 어드레스 결합 객체에 바인딩되지
{
COUT << "debug5"<< ENDL;

IF (m_bIsOwner) // 현재 오브젝트가 이미 스택을 결합하면, 제 릴리스
{
COUT << "debug6"<< ENDL ;
m_ptr 삭제;
}

COUT을 << "debug7는"<< ENDL는,

m_bIsOwner는 y.m_bIsOwner = // 전송 오너
}
다른 IF (y.m_bIsOwner) Y // 현재 오브젝트와 같은 하나 힙 결합, 및 Y는 소유자 객체 전송 Y의 현재 소유자에게 넣어
{
COUT << "debug8"<< ENDL;

m_bIsOwner = TRUE로;
}

COUT << "debug9"<< ENDL;

m_ptr y.release = (); // Y 더이상 때문에 소유자
}

COUT << "debug10"<< ENDL;

*이 반환하며 현재의 객체에 대한 참조를 리턴 //
}

// 소멸자
~ 다 auto_ptr은 ()
{
COUT << "debug11"<< ENDL;

// 전용 속성 소유자 따라서 자유로운 복제 방지 스택 해제되지 않은 경우 (m_bIsOwner)
{
COUT << "debug12"<< ENDL는;

m_ptr 삭제 // NULL 포인터는 짝수 m_ptr 관계 나무이다
}
}

// * 객체 과부하 연산자 오브젝트 포인터와 같이 수행 될 수있다 "보인다"너무 * P 동작
T & 연산자 (*)) (던져에서 const
{
<< "debug13"<< ENDL COUT을,

* GET ()를 호출;
}

// 과부하 객체 -> 오퍼레이터
T의 * 연산자 -> () 던져에서 const ()
{
<< COUT "debug14"<< ENDL;

리턴 GET ();
}

객체 바인딩의 주소를 얻을 //
) (던져에서 const) (T의 *의 GET을
{
COUT을 << "debug15"<< endl의를,

m_ptr 반환;
}

// 개체 소유자 속성 제거
) (던져에서 const) (T의 * 출시를
{
; << "debug16"<< endl의 COUT

;> = m_bIsOwner false로 - (합니다 (auto_ptr은 <T> *)가이)
; 반환 m_ptr을
}

: 개인
불리언 m_bIsOwner // 객체 소유자 플래그가 소유
결합하는 // 객체 포인터; T에 *를 m_ptr
}


INT의 main ()
{
{
COUT << "--------------- --------------- "<< ENDL;

생성자 명시가 있으므로 사용 // 에러, 형식 변환을 허용하지 않는다
// auto_ptr은 <INT> p = 새 (10) 지능;
}


{
COUT << "------------------------------"<< ENDL;

// OK
auto_ptr은 <INT> P ( INT 새로운 새 (10));
}


{
COUT << "------------------------------ "<< ENDL;

// 다음 코드는 런타임 심각한 오류가 실제로 스택의 내용을 삭제하려고
INT의 A = 10;
// auto_ptr은 <INT> P (A)]
}


{
COUT << "-------- ---------------------- "<< ENDL는,

auto_ptr과는 <INT>는 P- (새로운 새 INT (10));

// 에러, p는 않지만"는 같아 "P 삭제 대상의 본질 포인터는 정의되지 않은 동작이며
; // 삭제 P
}


{
------------------------ COUT <<" ------ "<< ENDL;

INT = Q * 새로운 새 INT (10)
auto_ptr은 <INT> P (Q);

// 에러 Q는 반복 한번 P 릴리스 해제 박리 아
// 삭제 Q;
}


{
COUT << "------------------------------"<< ENDL;

auto_ptr은 <INT> P0;

//이를 debug3 인쇄,하지만 debug4이 알고 왜
P0 = P0;
}


{
COUT << "------------------------------"<< ENDL;

auto_ptr은 <INT> P0 (새로운 새 INT (10));

//이 초기화 복사하지 그래서 인쇄 debug3가 있다는 것을 유의
auto_ptr은이 <INT> P1 = P0;
}


{
COUT은 << "----- ------------------------- "<< ENDL;

auto_ptr은 <INT> P0 (새로운 새 INT (10));
auto_ptr은 <INT> P1;

/ /,이 과제임을 모두가 debug3, debug4, debug5, debug7, 참고 debug9, debug10의 인쇄
// debug6 왜하지 않았다? 이 오브젝트 P1 소유자 아니므
P1 = P0;
}


{
COUT << "------------------------------"<< ENDL;

auto_ptr은 <INT> P0 (새로운 새 INT (10));
auto_ptr은 <INT> P1 (새로운 새 INT (20));

// 프린트 debug6 헤드 박리 객체 바인딩들 p1 때문에, 그렇지 않으면 메모리 누출 된 아
P0 = P1;
}


{
COUT << "------------------------------"< <ENDL;

auto_ptr은 <INT> P0 (새 INT (10));

// 소유자 P1로 옮겨
auto_ptr은 <INT> P1 (P0);

// 마지막 debug8 만나서
P0 = P1;
}

{
COUT << "--------------- --------------- "<< ENDL;

auto_ptr은 <INT>는 P- (새로운 새 INT (10));

// 뵙겠 debug13
COUT << ENDL << * P- 형;
}


{
COUT << "------------------------------"<< ENDL;

auto_ptr은 <A> P (새로운 새 A ( ));

// 마지막으로, debug15 당신을 만나고
P-> 재미 ();
}


{
COUT을 << "------------------------- ----- "<< ENDL;

auto_ptr은 <INT> P0 (새로운 새 INT (10));
auto_ptr은 <INT> P1 (P0)
auto_ptr은 <INT> P2 (P1)은,

실제로, P3이 마지막 // 우승자는 최종 소유자,따라서, P3 적층 체를 해제하는 작업
auto_ptr은 <INT> P3 (P2)
}


{
; << cout을 "------------------------------"<< endl의

원래 // 세상에, 메모리 누수, [] Q 삭제] 이제 Q 삭제 수행 소멸자;
INT = Q * 새로운 새 INT [3.]
auto_ptr은 <INT> P (Q)
}


{
COUT << "---------- -------------------- "<< endl의이,

오, 하나님, 메모리 누수, [] Q를 삭제 //이었다 소멸자 이제 질문을 삭제 수행 ;
INT * Q = 새로운 새 INT [3]
auto_ptr은 <INT> P- 형 (Q)는,

// 이미 메모리 방출 될 다음 문장을 반복하는, 상기
삭제 Q //;
}


// 마지막으로 설명 할 auto_ptr은 컨테이너에 적합하지 않다 우리가 나중에 다시하기 논의 할 예정 요소,


0을 반환;

}

원본 링크 : HTTPS : //blog.csdn.net/stpeace/article/details/45155487

블로그와 좋은 테스트 케이스, 아주 명확한 아이디어

추천

출처www.cnblogs.com/xcb-1024day/p/11331117.html