Koja je upotreba destruktora kao privatnog?

Koja je upotreba destruktora kao privatnog?

157
10 марта '09 в 21:59 2009-03-10 21:59 yesraaj je postavljen 10. ožujka u 21:59 2009-03-10 21:59
@ 9 odgovora

U načelu, u bilo kojem trenutku kada želite da neka druga klasa bude odgovorna za životni ciklus objekata vaše klase ili ako imate razloga da spriječite uništenje nekog objekta, možete učiniti destruktor zatvorenim.

Na primjer, ako napravite neku vrstu referencije na brojanje referenci, možete imati objekt (ili upravitelj koji je bio "prijatelj") koji je odgovoran za prebrojavanje broja referenci za sebe i njegovo brisanje kada broj dosegne nulu. Privatni dtor ne bi dopustio nikome da ga izbriše kada još uvijek postoje veze na njega.

U drugom slučaju, ako imate objekt koji ima upravitelja (ili sebe) koji ga može uništiti ili može odbiti uništiti ga, ovisno o drugim uvjetima u programu, kao što je otvorena veza s bazom podataka ili datoteka koja je napisana. Možda imate metodu "request_delete" u klasi ili upravitelju koji će provjeriti ovaj uvjet, ili će ili izbrisati ili odbiti i vratiti status koji će vam reći što je učinio. On je mnogo fleksibilniji od samo "brisanja".

139
10 марта '09 в 22:02 2009-03-10 22:02 odgovor je dao Paul Tomblin 10. ožujka u 10:02 2009-03-10 22:02

Takav objekt nikada ne može biti stvoren na stog. Uvijek na hrpi. I brisanje mora biti učinjeno preko prijatelja ili člana. Proizvod može koristiti jednu hijerarhiju objekata i prilagođeni upravitelj memorije - takve skripte mogu koristiti privatni dtor.

border=0
 #include <iostream> class a { ~a() {} friend void delete_a(a* p); }; void delete_a(a* p) { delete p; } int main() { a *p = new a; delete_a(p); return 0; } 
55
10 марта '09 в 22:06 2009-03-10 22:06 odgovor se daje dirkgently 10. ožujka u 22:06 2009-03-10 22:06

Ako ne želite da korisnici kontaktiraju destruktora, tj. želite da se objekt uništi samo drugim sredstvima.

http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx daje primjer gdje se objekt broji po referenci i treba ga uništiti samo objekt kada brojač ode na nulu.

43
10 марта '09 в 22:03 2009-03-10 22:03 je odgovorio Michaelu 10. ožujka u 10:03 2009-03-10 22:03

COM koristi ovu strategiju za brisanje instance. COM čini destruktor zatvorenim i pruža sučelje za brisanje instance.

Evo primjera kako će izgledati način izdavanja.

 int MyRefCountedObject::Release() { _refCount--; if ( 0 == _refCount ) { delete this; return 0; } return _refCount; } 

ATL COM objekti su vrhunski primjer ovog uzorka.

15
11 марта '09 в 4:14 2009-03-11 04:14 odgovor je dat Vinay 11. ožujka u 4:14 2009-03-11 04:14

Dodavanje već postojećih odgovora; Privatni konstruktori i destruktori su vrlo korisni pri implementaciji tvornice , gdje se objekti koji se stvaraju moraju odabrati na hrpi. Objekti će općenito biti kreirani / izbrisani od strane statičnog člana ili prijatelja. Tipičan primjer uporabe:

 class myclass { public: static myclass* create() // Factory { return new myclass(); } static void destroy(myclass* ptr) { delete ptr; } private: myclass() { ... } // Private CTOR and DTOR ~myclass() { ... } // } int main () { myclass m; // error: ctor and dtor are private myclass* mp = new myclass (..); // error: private ctor myclass* mp = myclass::create(..); // OK delete mp; // error: private dtor myclass::destroy(mp); // OK } 
5
17 мая '15 в 21:40 2015-05-17 21:40 odgovor je dan nav 17 svibanj '15 u 21:40 2015-05-17 21:40

Klasa se može izbrisati sama. Korisno ako pokušavate prebrojati prebrojani objekt. Tada samo metoda oslobađanja može izbrisati objekt, što pomaže u izbjegavanju pogrešaka.

5
10 марта '09 в 22:03 2009-03-10 22:03 odgovor je dao Roland Rabien 10. ožujka u 10:03 2009-03-10 22:03

Diggly pogrešno. Evo primjera objekta s privatnim c-tor i d-tor stvorenim na stog (ovdje koristim statičku funkciju člana, ali to se može učiniti pomoću funkcije prijatelja ili klase prijatelja).

 #include <iostream> class PrivateCD { private: PrivateCD(int i) : _i(i) {}; ~PrivateCD(){}; int _i; public: static void TryMe(int i) { PrivateCD p(i); cout << "inside PrivateCD::TryMe, p._i = " << p._i << endl; }; }; int main() { PrivateCD::TryMe(8); }; 

Ovaj kod će proizvesti rezultat: unutar PrivateCD :: TryMe, p._i = 8

3
10 марта '11 в 12:53 2011-03-10 12:53 odgovor je dat misicd 10. ožujka '11 u 12:53 2011-03-10 12:53

Znam da ste pitali za privatnog destruktora. Evo kako koristim zaštićene. Ideja je da ne želite izbrisati glavnu klasu s pokazivačem na klasu, koja dodaje dodatne funkcije glavnoj klasi.
U primjeru ispod, ne želim da se GuiWindow ukloni pomoću pokazivača HandlerHolder.

 class Handler { public: virtual void onClose() = 0; protected: virtual ~Handler(); }; class HandlerHolder { public: void setHandler( Handler* ); Handler* getHandler() const; protected: ~HandlerHolder(){} private: Handler* handler_; }; class GuiWindow : public HandlerHolder { public: void finish() { getHandler()->onClose(); } virtual ~GuiWindow(){} }; 
3
10 марта '09 в 23:17 2009-03-10 23:17 odgovor je dao Mykola Golubyev 10. ožujka u 23:17 2009-03-10 23:17

To može biti način rješavanja problema u sustavu Windows, gdje svaki modul može koristiti različitu gomilu, na primjer Debug heap. Ako se problem ne riješi ispravno, može doći do loših stvari .

2
10 марта '09 в 22:09 2009-03-10 22:09 odgovor je dao Jared Oberhaus 10. ožujka u 22:09 2009-03-10 22:09

Ostala pitanja o oznakama ili Postavite pitanje