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

  • jattila48

    aktív tag

    Kétfázisú inicializálás az, amikor az objektumot a konstruktora nem inicializálja teljesen, hanem még egy inicializáló tfv.-t kell meghívni ahhoz, hogy az objektum használható legyen. Akkor szokták használni, ha az inicializálás során virtuális tfv.-t kell meghívni, vagy a konstruktor nem dobhat exception-t. A kétfázisú inicializálást általában kerülendőnek tekintik. Azonban szerintem kifejezetten hasznos is lehet, és nagyban egyszerűsítheti a megfelelő resource kezelést pl. memory leak elkerülésére használható. Ha pl. van egy objektumunk, aminek inicializálása során két memória foglalást végez, előfordulhat hogy az első allokáció sikeres, a második pedig nem. Konstruktorral megoldva ilyenkor auto_ptr-t használhatunk, mert az első pointert fel kell szabadítani, mielőtt a második allokáció sikertelensége miatt a konstruktor exception-t dob. Ilyenkor az objektum destruktora nem fut le, mert csak teljesen megkonstruált objektumra fut le a destruktor, ha az kilép a scope-ból. Na már most kétfázisú inicializálással az objektumot a konstruktora úgy hozza létre, hogy a szóban forgó két pointert NULL-lal inicializálja, majd az inicializáló tfv. elvégzi a szükséges allokációkat. Ha valamelyik allokáció nem sikerül, akkor az init tfv. exception-t dob, vagy false-val tér vissza, de a sikertelen allokáció eredményeként a pointer NULL marad. Az objektum destruktora csak a nem NULL pointert szabadítja fel, a NULL-t békén hagyja.

    class A {
    public:
    A():c(NULL),d(NULL){}
    ~A();
    bool init(int,int);
    private:
    char * c;
    char *d;
    }

    A::~A()
    {
    if(c!=NULL)delete[] c;
    if(d!=NULL)delete[] d;
    }

    bool A::init(int n,int m)
    {
    c=new char[n];
    d=new char;
    return true;
    }

    void main(void)
    {
    try{
    A a; //Ez mindenkepp lefut, nem dob exception-t
    a.init(10,0x7fffffff); //A::d-nek tul nagy memoriat akarunk foglalni, ezert exception-t dob
    }
    catch(std::bad_alloc &){
    std::cout << "Memory allpc error";
    }
    //Itt a lefoglalt A::c felszabadult, nincs memory leak
    }

    A lényeg az, hogy a try blokk végén az A destruktora lefut, mert az A a objektum konstruktora mindenképp lefutott. Kicsit olyan ez, mintha az A osztály maga is egy "smart pointer" lenne.
    Mit szóltok hozzá? Ugye nem is feltétlenül rossz a kétfázisú inicializálás?

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