2013-01-09 31 views
7

Mam klasy RAII:RAII manipulacja zasobami


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 

wiem kiedy zabraknie zakresu mój destruktor zostanie wywołana. ~RAII() {delete P_};

Moje pytanie brzmi:

Jak to nazwać mój destruktor?

+0

Dlaczego nie używasz 'std :: auto_ptr' (lub' std :: unique_ptr', jeśli robisz C++ 11)? – masaers

+2

Magia kompilatora :) http://en.wikipedia.org/wiki/Destructor_(computer_programming) – sarat

+1

Czy klasa RAII nie potrzebuje skopiować konstruktora i operatora przypisania? –

Odpowiedz

6

Po zgłoszeniu wyjątku i przejściu kontroli od bloku try do programu obsługi, czas działania w C++ wywołuje destruktory dla wszystkich obiektów automatycznych tworzonych od początku bloku try. Ten proces nazywa się rozwijaniem stosu. Obiekty automatyczne są niszczone w kolejności odwrotnej do ich budowy. (Obiekty automatyczne są obiektami lokalnymi, które zostały zadeklarowane jako automatyczne lub rejestrujące się lub nie zostały zadeklarowane jako statyczne lub zewnętrzne.Plik automatyczny x jest usuwany za każdym razem, gdy program wychodzi z bloku, w którym zadeklarowano x.)

Jeśli podczas pracy zostanie zgłoszony wyjątek Konstrukcja obiektu złożonego z podobiektów lub elementów tablicowych powoduje, że destruktory są wywoływane tylko dla tych podobiektów lub elementów tablicy pomyślnie skonstruowanych przed wyrzuceniem wyjątku. Destruktor lokalnego obiektu statycznego zostanie wywołany tylko wtedy, gdy obiekt został pomyślnie skonstruowany.

Jeśli podczas rozwijania stosu destruktor zgłasza wyjątek i ten wyjątek nie jest obsługiwany, wywoływana jest funkcja terminate().

Przykład: patrz demontaż poniżej. Zobaczysz, że destruktor jest już popchnięty na stos.

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

Kompilator automatycznie generuje kod wywołujący destruktory zmiennych lokalnych. *


* Technicznie rzecz biorąc, są one znane jako "przedmiotów z automatycznym okres przechowywania". Powinno być jasne, dlaczego!

+0

Mam przeczucie, że to nie jest dla niego pomocne. W jaki sposób "automatycznie generuje" kod? – Pubby

+5

@Pubby: Jak kompilator robi cokolwiek? –

+0

Po prostu dodaj, gdzie destruktory zostały dodane i krótki przegląd zastosowanego algorytmu deterministycznego lub coś takiego. – Pubby