Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Konstruktor i izuzetak

[es] :: C/C++ programiranje :: Konstruktor i izuzetak

Strane: 1 2

[ Pregleda: 8198 | Odgovora: 29 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

karas

Član broj: 5574
Poruke: 482
*.77.eunet.yu.



+1 Profil

icon Konstruktor i izuzetak17.10.2004. u 18:06 - pre 235 meseci
Ako je u konstruktoru bachen izuzetak, da li je dotichni objekat delimichno stvoren ili nije uopshte? Ako je zauzeta memorija u konstruktoru, kako je osloboditi?

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.bos.east.verizon.net.



+6 Profil

icon Re: Konstruktor i izuzetak17.10.2004. u 19:09 - pre 235 meseci
Objekat nije konstruisan dok se konstruktor potpuno ne izvrši. Jedino je problem ako uradiš ovako nešto:

Code:

Klasa::Klasa(bool crkni) {
  m_niz = new char[50];
  if (crkni)
    throw Izuzetak;  
}


U tom slučaju imaš curenje memorije jer si zauzeo niz od 50 bajtova a nisi ga oslobodio. Rešenja mogu da budu:

1) (bolje) da m_niz deklarišeš ne kao pointer na char,već kao std::vector<char> i onda nema brige za new-delete.
2) (lošije) da počistiš memoriju pre nego što baciš izuzetak:

Code:

Klasa::Klasa(bool crkni) {
  m_niz = new char[50];
  if (crkni) {
    delete [] m_niz;
    throw Izuzetak;
    }  
}


 
Odgovor na temu

Reljam
Relja Markovic
San Francisco

Član broj: 531
Poruke: 1793
*.client.comcast.net.



+18 Profil

icon Re: Konstruktor i izuzetak17.10.2004. u 19:17 - pre 235 meseci
Ili jos bolje da ne koristis izuzetke u C++u jer ne rade bas uvek kako treba, kao sto je DT upravo pokazao.
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.bos.east.verizon.net.



+6 Profil

icon Re: Konstruktor i izuzetak17.10.2004. u 19:58 - pre 235 meseci
Recimo da je ovo pitanje (koristiti ili ne koristiti izuzetke) dosta sporno. Koliko vidim, manje-više svi C++ magovi (izbegavam izraz "gurui", hehehe): Stroustrup, Sutter, Meyers... smatraju da ih treba koristiti, a jedan od najčešćih argumenata im je upravo ova situacija. Kako ćeš da prijaviš grešku u slučaju da konstruktor nije u stanju da konstruiše objekat? Sa druge strane, pisati exception-safe kod nije baš dečja igra i mnogi su se opekli na tom terenu. Nisam ni sam siguran, da budem iskren.
 
Odgovor na temu

Reljam
Relja Markovic
San Francisco

Član broj: 531
Poruke: 1793
*.client.comcast.net.



+18 Profil

icon Re: Konstruktor i izuzetak17.10.2004. u 20:18 - pre 235 meseci
Ti magovi su tu da bi izmisljali nove stvari i dalje razradjivali postojace - to je isti set ljudi koji je izmislio cin i cout. Naravno da su to inteligentni ljudi, naravno da imaju iskustva, ali to ne znaci da je svako njihovo ponudjeno resenje (recimo exceptioni) prilagodjeno problemu. Ja nazalost nemam mnogo iskustva sa C++ exceptionima, uvek su mi ovakvi problemi izletali i onda sam odlucio da ih ne koristim. Koliko sam shvatio, postoji i dubljih problema sa njima od pravilnog odvijanja steka, pogotovu kada zadjemo u DLLove (propagacija exceptiona) i drzanje lockova. Izgleda kao da bi deo resenja bio da se za sve koriste smart pointeri, da sve bude wrappovano (fajlovi, lokovi, sve), ali onda smo se toliko priblizili MC++u da mozda sve to ni nema smisla.

Ne znam. Jos nisam video kompleksniji program koji koristi exceptione 'kako treba' (video sam neke koji koriste exceptione na par mesta, cisto reda radi), ali to naravno ne znaci da tako nesto ne postoji.

A inace u konstruktoru ni ne treba alocirati memoriju, to treba ostaviti za Initialize (barem u C++u).
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
*.bos.east.verizon.net.



+6 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 01:07 - pre 235 meseci
Au, bre Relja. Vi "grafičari" koristite C++ kao C sa klasama. Razumem da se plašiš "ovreheada", ali recimo boost::scoped_array nema nikakav overhead u odnosu na gole pointere. Onda lepo uradiš nešto kao:

Code:

Klasa::Klasa(bool crkni) : m_niz(new char[50]) {
  if (crkni)
    throw Izuzetak;  
}


i nema da te boli glava.

I inače tvrdo verujem da C++ ima budućnost samo ako naučimo da ne koristimo gole pointere osim kad je to apsolutno neophodno, već da sve "zamotavamo" u pametne pointere. Skoro je bio jedan mnogo lep članak na CP-u o korišćenju smart pointera za automatsko čišćenje Win handleova. Jednostavno postaje besmisleno da se u 21-om veku gubi vreme na new-delete i open-close bugove.
 
Odgovor na temu

Reljam
Relja Markovic
San Francisco

Član broj: 531
Poruke: 1793
*.client.comcast.net.



+18 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 03:04 - pre 235 meseci
Ne radi se o overheadu, to uglavnom nije problem. Vise se radi o drzanju netrivijalnih objekata (sistemski hendlovi, lokovi, itd). Nije problem u tome sto si ti napisao, taj kod je ok, problem je kada se desi exception u delu koji ne ocekujes - recimo kada pozoves tudju komponentu. Takodje je problem sta se desava sa ovim sistemskim objektima, koji mozda nece biti oslobodjeni kako treba. Zez kod exceptiona je to sto te tera da ih koristis za sve, odnosno vrlo je tesko lokalizovati exceptione na samo deo programa. Jer ako komponenta A koristi exceptione, onda svako mesto gde se A koristi moze potencijalno da pukne, a ti onda moras da se potrudis da svi sistemski resursi na svim tim mestima budu na pravi nacin releasovani kada A baci exception.

A new-delete bagovi inace nisu cesta pojava, barem ne u ovome sto ja radim - vecina bafera je prealocirana ili se unapred tacno zna sta ide gde.
 
Odgovor na temu

rivan
Ivan Radovanović

Član broj: 1901
Poruke: 71
*.preco1990.com.

ICQ: 212235650


Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 07:46 - pre 235 meseci
ovakve situacije (exception u konstruktoru) se resavaju funkcionalnim try-catch blokovima - primer iz msdn-a:

C::C(int ii)
try // function-try block
: i(f(ii))
{
// body of function goes in try block
}
catch (...)
{
// handles exceptions thrown from the constructor-initializer
// and from the constructor function body
printf("\nIn the catch block");
}
 
Odgovor na temu

leka
Dejan Lekić
senior software engineer, 3Developers
Ltd.
London, UK

Član broj: 234
Poruke: 2534
..31.216.81.gus.vf.siwnet.net.

Sajt: dejan.lekic.org


+2 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 12:14 - pre 235 meseci
Ne znam za vas - ja licno reeeeeeeeeeetko koristim obradu izuzetaka u C++-u, takodje retko koristim i STL (samo kad moram). Stavise, izbegavam i RTTI (osim u slucaju kad mi zaista treba).
Dejan Lekic
software engineer, MySQL/PgSQL DBA, sysadmin
 
Odgovor na temu

leka
Dejan Lekić
senior software engineer, 3Developers
Ltd.
London, UK

Član broj: 234
Poruke: 2534
..31.216.81.gus.vf.siwnet.net.

Sajt: dejan.lekic.org


+2 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 12:15 - pre 235 meseci
Citat:
I inače tvrdo verujem da C++ ima budućnost samo ako naučimo da ne koristimo gole pointere osim kad je to apsolutno neophodno, već da sve "zamotavamo" u pametne pointere.


Tada ce to prestati da bude C++.
Dejan Lekic
software engineer, MySQL/PgSQL DBA, sysadmin
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
66.228.70.*



+6 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 13:33 - pre 235 meseci
@Relja: Pazi, izuzetke iz "tuđeg" koda u principu ne možeš da izbegneš nikako. Ako operator new ne može da alocira memoriju on će da baci izuzetak std::bad_alloc. Drugi primer, u slučaju da se desi access violation, Windows će da baci SEH, koji može da se uhvati sa catch(...) ili da se mapira na neki drugi izuzetak. Ako koristiš recimo DTL za pristup bazama podataka, dobićeš izuzetak kad god neka operacija sa bazom ne uspe. Jednostavno, izuzeci su legitiman deo C++a i treba znati kako da se radi sa njima, a ne "izbegavati ih".

@rivan: Ne znam u kom kontekstu je dat taj kod, ali to je školski primer kako ne treba raditi u konstruktoru. U slučaju izuzetka dobićeš loše inicijalizovan objekat a nećeš znati, pa ćeš ga koristiti kao da je lepo inicijalizovan i nastradaćeš. Pusti izuzetak da ode iz konstruktora i koristi try-catch kad kreiraš nov objekat te klase.

Destruktori su potpuno suprotan primer. Ne treba pustiti izuzetak da napusti destruktor ni po koju cenu.

@Leka: Ja sam odavno primetio da si ti u duši C programer. Da me ne shvatiš pogrešno, nema ničeg lošeg u tome i potpuno je legitimno koristiti C++ kao "bolji C", ali grešiš kada kažeš da su "sirovi" pointeri bitno obeležje C++a. Najvažnija osobina C++a je da sam biraš nivoe apstrakcije koje želiš da koristiš i da plaćaš samo za ono što zaista i koristiš. Siguran sam da u najvećem broju slučajeva nema racionalnog razloga za manuelno oslobađanje resursa, a u kodu koji koristi izuzetke je praktično nemoguće izbeći razna "curenja" (memorije i drugih resursa) ako ne koristiš "pametne omotače" umesto pointera i dugih handleova.

Da rekapituliram. Moguće je praviti ispravan kod ako:
1) Manuelno oslobađate resurse ali ne koristite izuzetke (teži način)
2) Automatski oslobađate resurse i koristite (ili ne) izuzetke (lakši način).

 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.94.EUnet.yu.



+1 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 16:24 - pre 235 meseci
Code:

Klasa::Klasa(bool crkni) {
  m_niz = new char[50];
  if (crkni) {
    delete [] m_niz;
    throw Izuzetak;
    }  
}


A ako je bachen izuzetak pri stvaranju petog chlana niza (npr. nema memorije) da li delete brishe samo ona chetiri koja su stvorena pre izuzetka?

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
66.228.70.*



+6 Profil

icon Re: Konstruktor i izuzetak18.10.2004. u 16:33 - pre 235 meseci
Ako operator new baci izuzetak, onda je do njega da "počisti" memoriju. Uostalom, u tom slučaju tvoj delete neće ni da se izvrši jer ako new baci izuzetak, izvršavanje koda u konstruktoru se prekida na tom mestu.

Još jednom ti savetujem da batališ te new-delete kombinacije i da koristiš smart pointere. Evo jednog lepog članka na tu temu:

http://www.artima.com/cppsource/bigtwo.html


 
Odgovor na temu

rivan
Ivan Radovanović

Član broj: 1901
Poruke: 71
*.preco1990.com.

ICQ: 212235650


Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 07:31 - pre 235 meseci
Code:

class a {
    char* an, *bn;
private:
    void Pocisti() {
        delete[] an;
        delete[] bn; }
public:
    a() 
        try: an(0), bn(0) {
            an = new char[1000];
            bn = new char[1000000]; // nesto puno sto ce da baci exception
        }
        catch(...) {

            Pocisti();
            throw 1;    // pusti dalje izuzetak
        }
    ~a() {
        Pocisti();
    }
};


@Dragi Tata
Naravno da nisam mislio da konstruktor "guta" izuzetak

U slucaju da nema catch bloka ako se pri alociranju bn javi izuzetak memorija zauzeta za an ce iscureti.
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
66.228.70.*



+6 Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 13:21 - pre 235 meseci
@rivan: Onaj prvi primer je "gutao" izuzetke, ili bar nije bilo očigledno da ih ne guta.

A što se tvog primera tiče (mada nevezano direktno za našu raspravu), razmisli šta će da se desi ako uradiš:

Code:

a prvi;
a drugi = prvi;


I još nešto, mislim da si hteo da kažeš samo throw a ne throw 1 u catch bloku.

A sad pogledaj ovo i sam kaži šta je bolje:

Code:

class a {
    std::vector<char> an, bn;
public:
    a() 
       {
       an.resize(1000);
       bn.resize(1000000);
       }
};


Nema da te boli glava oko čišćenja, kod je exception-safe a i copy semantika je ispravna za razliku od tvog primera.

Stvarno mi se čini da je osnovni problem sa C++om naopak način na koji su pisane mnoge knjige i na koji se uči ovaj jezik u školama. Umesto da nauče ljude prvo da koriste standardnu biblioteku i druga gotova rešenja, oni krenu da gnjave početnike sa alociranjem i dealociranjem memorije pa ih ubiju u pojam.

C++ može da bude jezik visokog nivoa i nema razloga da se ne koristi na taj način kad god je to moguće.
 
Odgovor na temu

rivan
Ivan Radovanović

Član broj: 1901
Poruke: 71
*.preco1990.com.

ICQ: 212235650


Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 14:55 - pre 235 meseci
Citat:

Code:

a prvi;
a drugi = prvi;



@Dragi Tata
Ovo je podla zamena teza ;-)
Nije mi bila namera da ikog ucim kako se pise klasa koja sadrzi dinamicki alocirane objekte (sto je razlog sto nisam napisao operator = ni kopi konstruktor), nego da ilustrujem kako je moguce ispravno uraditi citavu konstrukciju objekta u konstruktoru i oporaviti se od eventualne greske bez curenja memorije.

Sto se tice throw istina je da sam hteo to da kazem ali u trenutku nisam mogao da se setim da li c++ ima samo throw bez argumenata za prosledjivanje izuzetka dalje (moja greska) - a ni throw 1; ne menja poentu

Sto se tice toga sta je bolje - ne postoji resenje koje je bolje u svakom slucaju - nekad ti je vazno vreme razvoja, a nekad vreme izvrsavanja...
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
66.228.70.*



+6 Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 15:28 - pre 235 meseci
Stvarno nisam hteo da ti "spuštam", već samo da pokažem da upotrebom standardnih kontejnera i pametnih pointera ubijemo više muva jednim udarcem: dobijemo exception-safe kod i ispravnu copy semantiku.

Citat:
rivan: Sto se tice toga sta je bolje - ne postoji resenje koje je bolje u svakom slucaju - nekad ti je vazno vreme razvoja, a nekad vreme izvrsavanja...


Slažem se da ne postoje "univerzalno bolja" rešenja, ali ako su ti performanse izgovor da uopšte ne koristiš standardnu biblioteku, onda praviš veliku grešku koja se zove "Premature optimization". Otkud znaš da je rešenje sa golim pointerima brže nego sa vektorom? Ako je brže, koliko je brže? Ako je zaista toliko brže da ugrožava performanse tvoje aplikacije (a to si utvrdio merenjem a ne nagađanjem), onda možeš da uradiš npr nešto ovako:

Code:

class a : boost::noncopyable {
    boost::scoped_array<char> an, bn;
public:
    a() : an(new char[1000]), bn(new char[1000000]) 
        {}
};


Ovo je svaki iole normalan kompajler u stanju da izoptimizuje tako da nema nikakvih penala u performansama. Bukvalno 0.
 
Odgovor na temu

karas

Član broj: 5574
Poruke: 482
*.66.eunet.yu.



+1 Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 17:16 - pre 235 meseci
Hvala na chlanku, razjasnio je neke stvari.
Nekako imam utisak (mozzda i pogreshan) da su auto_ptr, vector i slichne olakshice uvek usput pomenute, kao da se "prave" stvari moraju raditi preko golih pokazivacha.
Da li su funkcije iz C biblioteke (<cstdio> i dr.) chiste C funkcije ili mozze neka od njih da baci izuzetak? Da li je za svaku funkciju iz C++ biblioteke jasno deklarisano da baca izuzetak? Da se ne desi da program puca zbog bachenog izuzetka za koji nisam ni znao da postoji.

Sveti Avgustin: "Dobar hrišćanin treba da se kloni matematičara i svih onih koji daju lažna proročanstva. Postoji opasnost da su matematičari već sklopili pakt sa Đavolom, da pomrače čovekov um i da ga okuju okovima pakla."
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
66.228.70.*



+6 Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 17:33 - pre 235 meseci
C funkcije ne bacaju izuzetke. Što se ostalog tiče, sve zavisi od kvaliteta dokumentacije koju imaš. U principu, svaka funkcija koja koristi new za alociranje memorije (kao što je vector::resize) može da baci izuzetak.

Ako nameravaš da koristiš auto_ptr, obrati pažnju da ima vrlo čudnu copy semantiku. Mislim da je bezbednije koristiti Boost smart pointere ako ne znaš tačno kako auto_ptr radi. Pogledaj recimo ovaj članak:

http://www.gotw.ca/publications/using_auto_ptr_effectively.htm
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
66.228.70.*



+6 Profil

icon Re: Konstruktor i izuzetak19.10.2004. u 17:38 - pre 235 meseci
Evo, naleteh na jedan lep člančić o dilemama "izuzeci ili ne?"

http://www.dslextreme.com/users/fabrizioo/rant/en/except.html
 
Odgovor na temu

[es] :: C/C++ programiranje :: Konstruktor i izuzetak

Strane: 1 2

[ Pregleda: 8198 | Odgovora: 29 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.