Hirdetés

Új hozzászólás Aktív témák

  • Karma
    félisten

    Gondolkoztam még ezen, hogy miért lesz átláthatóbb a függvény, ha egyetlen return van, de nem látom be, miért is lenne ez jó. Szerintem azonnal áttekinthetővé válik a dolog, hogy ha valami feltétel, amire várunk, már az elején teljesül, akkor ne is folytassa tovább a vizsgálgatást, ez gondolom akár gyorsaság szempontjából sem lehet elhanyagolható. Jester01-gyel értek egyet, sokkal kevésbé lesz átlátható a függvény a sok if-else elágazás miatt. A tanított anyagokban is mindenhol akár több return utasítás is van bizonyos feltételek teljesülése esetén.
    De most tényleg, miért lenne baj, ha több return van? :DDD
    ___________________
    "Auto-pointereknél nem para a felszabadítás több return esetén, de pl. CleanupStacknél sokkal bonyolultabb a memóriát karban tartani."
    Ebből sokat nem értettem, ezt röviden el tudod magyarázni? :B

    Pedig ha azok a fogalmak megvannak, az első kérdésre is könnyebb válaszolni. Persze mindkettő C++ minta (sőt, a második csak és kizárólag Symbian C++-ban van), ezért C-nél még nem kavar be.

    Auto pointer: egy olyan objektum, ami ha megsemmisül a stacken, magával ránt egy hozzárendelt heapen lévő objektumot is, így amikor az auto_ptr scope-on kívülre kerül, a másik objektum biztosan megsemmisül. Ez egy egyszerűsítés, így biztosan nem maradhat meg a heapen lévő objektum pl. azért, mert valahova berakott az ember még egy returnt, és elfelejtette felszabadítani ott is a memóriát :U

    Valahogy így néz ki:

    int valami()
    {
    int *valami_int = new int; // heapen hoztam letre, mint a malloc C-ben
    auto_ptr<int> valami_ptr(valami_int); // az auto pointerre bizom a felszabaditast
    ...
    // ugy hasznalom, mint egy pointert
    *valami_ptr = 5; // a valtozo erteket valtoztatom itt
    ...
    return 0; // valami_ptr megsemmisul -> valami_int is torlodik
    ...
    return 1; // valahol mashol ugyanez lezajlik
    }

    Ha nem lenne ez az auto_ptr, akkor mindkét return elé oda kéne írni explicite a következő sort (ez a free C++-os megfelelője), amit könnyen kifelejthet az ember, ha utólag hackelget bele a függvénybe, memory leaket okozva.

    delete valami_int;

    Cleanup Stack: Amikor a Symbiant írták, még nagyon fejletlenek voltak a C++ fordítók, kivételdobáskor a stacken lévő objektumokra nem hívódott meg a destruktor, ami mindenféle vicces hibához vezethetett, többek között "csak" memory leakhez. Ezért a nagyokosok kitalálták, hogy "csináljunk saját kivételkezelést!", megalkották a Leave-eket és a Cleanup Stacket.

    Minden heapen lefoglalt objektumot, ami nem tagváltozó, fel kell kézzel rakni a CleanupStackre, és persze le is kell venni onnan, ha olyan műveletek jönnek, amik kivételt (konkrétan leave-et) dobhatnak. Tehát mindig figyelni kell a programozónak arra, hogy mikor mi van rajta, mikor melyik objektum kinek a felelősségébe tartozik, és ennek megfelelően variálni.

    Na itt jön be, hogy ha több return utasítás van, akkor kitörhet a káosz, a függvény különböző részein más lehet a CleanupStack állapota, minden returnnél megfelelően adminisztrálni kell, és ha bármit változtatni kell, mindenhol át kell írni...

    Példakód:
    TInt CSomething::DoSomethingL()
    {
    TInt result = 0;

    CSomethingBig *big = CSomethingBig::NewL();
    CleanupStack::PushL(big);

    RSomethingResource res;
    CleanupClosePushL(res);

    result = res->DoSomethingDangerousL(big); // ha ez dob egy leave-et, res bezarodik, big megsemmisul

    CleanupStack::PopAndDestroy(2, big); // mindket elemet megsemmisiti
    return result;
    }

    Ezt a kódot nem magyaráznám túl, ha nem baj, hiszen csak random firkáltam. A lényeg az, hogy a PopAndDestroy hívást minden return előtt meg kell hívni, pontosan.

Új hozzászólás Aktív témák