2013-01-09 30 views
7

Tôi có một lớp RAII:RAII xử lý tài nguyên


template<typename T> 
    class RAII 
    { 
    public: 
    explicit RAII(T* p = 0): p_(p){} 

    ~RAII() {delete p_;} 

    T& operator*() const { return p_;} 
    T* operator‐>() const{ return p_;} 
    }; 

{ 

RAII<std::vector<int>> r(new std::vector<int>()); 
std::cout<<r­‐>size()<<std::endl; 

} // The std::vector<int> is automatically deallocated 

Tôi biết khi tôi chạy ra khỏi phạm vi destructor của tôi sẽ được gọi. ~RAII() {delete P_};

Câu hỏi của tôi là:

như thế nào gọi destructor của tôi?

+0

Tại sao bạn không sử dụng 'std :: auto_ptr' (hoặc' std :: unique_ptr' nếu bạn đang thực hiện C++ 11)? – masaers

+2

Phép thuật của trình biên dịch :) http://en.wikipedia.org/wiki/Destructor_(computer_programming) – sarat

+1

Lớp RAII có cần bản sao của hàm tạo và toán tử gán không? –

Trả lời

6

Khi ngoại lệ được ném và kiểm soát chuyển từ khối thử sang trình xử lý, thời gian chạy C++ gọi destructors cho tất cả các đối tượng tự động được tạo từ khi bắt đầu khối thử. Quá trình này được gọi là stack unwinding. Các đối tượng tự động bị phá hủy theo thứ tự ngược lại của công trình xây dựng. (Các đối tượng tự động là các đối tượng cục bộ đã được khai báo tự động hoặc đăng ký, hoặc không khai báo tĩnh hoặc extern. Một đối tượng tự động x sẽ bị xóa bất cứ khi nào chương trình thoát khỏi khối trong đó x được khai báo.)

Nếu một ngoại lệ được ném trong xây dựng một đối tượng bao gồm các phần tử con hoặc các phần tử mảng, các trình phá hủy chỉ được gọi cho các phần tử con hoặc các thành phần mảng được xây dựng thành công trước khi ngoại lệ được ném ra. Một destructor cho một đối tượng tĩnh cục bộ sẽ chỉ được gọi nếu đối tượng được xây dựng thành công.

Nếu trong khi xếp thư mời một trình phá hủy ném một ngoại lệ và ngoại lệ đó không được xử lý, hàm terminate() được gọi.

Ví dụ: Xem phần tháo gỡ bên dưới. Bạn sẽ thấy destructor đã được đẩy lên stack.

class Test 
{ 
public: 
    Test() 

    { 
     std::cout<<"C'tor\n"; 
    } 
    ~Test() 
    { 
     std::cout<<"D'tor\n"; 
    } 
} 
int main()//_TCHAR* argv[]) 
{ 
Test(); 
} 
00DD9C30 55     push  ebp 
00DD9C31 8B EC    mov   ebp,esp 
00DD9C33 81 EC CC 00 00 00 sub   esp,0CCh 
00DD9C39 53     push  ebx 
00DD9C3A 56     push  esi 
00DD9C3B 57     push  edi 
00DD9C3C 8D BD 34 FF FF FF lea   edi,[ebp-0CCh] 
00DD9C42 B9 33 00 00 00  mov   ecx,33h 
00DD9C47 B8 CC CC CC CC  mov   eax,0CCCCCCCCh 
00DD9C4C F3 AB    rep stos dword ptr es:[edi] 
    23: 
    24:  Test(); 
00DD9C4E 8D 8D 3B FF FF FF lea   ecx,[ebp-0C5h] 
00DD9C54 E8 67 7C FF FF  call  Test::Test (0DD18C0h) 
00DD9C59 8D 8D 3B FF FF FF lea   ecx,[ebp-0C5h] 
00DD9C5F E8 03 76 FF FF  call  Test::~Test (0DD1267h) 
    25: } 
4

Trình biên dịch sẽ tự động tạo mã để gọi hàm hủy của biến cục bộ. *


* Về mặt kỹ thuật, chúng được gọi là "đối tượng với thời gian lưu trữ tự động". Nó phải rõ ràng lý do tại sao!

+0

Tôi có cảm giác điều này không hữu ích cho anh ta. Làm thế nào để nó "tự động tạo ra" mã? – Pubby

+5

@Pubby: Trình biên dịch hoạt động như thế nào? –

+0

Chỉ cần đăng nơi mà các destructors được thêm vào và một tổng quan ngắn gọn về thuật toán xác định được sử dụng hoặc một cái gì đó. – Pubby

Các vấn đề liên quan