Hirdetés

Keresés

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

  • dobragab

    addikt

    válasz jattila48 #3064 üzenetére

    Az std::string filename RAII-ra átalakításánál úgy gondoltam, a kissé kreatívabban oldod meg. Pl. kap még egy paramétert a privát ctor, ami átveszi az erőforrást, és felszabadítja. Így effektíven a D-nek a read_from_file a konstruktora. A hármas szabállyal most nem tököltem.

    class D : public B
    {
    std::string filename;
    FILE * fp = nullptr;

    D(FILE * fp,
    std::string const& filename,
    std::vector<std::string> const& param1,
    std::map<int, int> const& param2) :
    B{param1, param2},
    filename{filename},
    fp{fp}
    { }

    public:

    static D read_from_file(std::string const& filename)
    {
    fp = fopen(filename.c_str(), "r+b");

    std::vector<std::string> myvec;
    std::map<int, int> mymap;

    // load data from file to my___

    return D{fp, filename, myvec, mymap};
    }

    virtual void pure_virtual_func() override
    { }

    virtual ~D()
    {
    fclose(fp);
    }
    };

    Tehát a fájl megnyitás, és a memória terület foglalás nem a D ctor-ában történik, viszont az erőforrás felszabadítást (legalábbis a fájl lezárást) a dtor-ban akarod megoldani.

    Nem ott van, szándékosan. Ha jól értem, B leszármazottai abban különböznek egymástól, hogy más külső reprezentációja. B-nek az a dolga, hogy ezeken felülemelkedjen, nélkülük legyen teljes értékű. Épp ezért B-nek nem szabad függnie tőle, azt oldják meg a leszármazottak.

    Tényleg jobb lenne D konstruktorába pakolni az allokációt, de ebben a formában nem lehet megoldani. Az ős-ctor hívása mindenképp előbb van, mint a ctor törzse, úgyhogy arra nincs esélyed normálisan megoldani.

    Ez egy felemás RAII lenne, ami szerintem koncepcionálisan hibás.

    std::shared_ptr és make_shared? Szerintem ez a megoldás pont arra hasonlít. Mindenesetre a kötelezően hívandó init() szerintem ennél sokkal büdösebb: el lehet felejteni a hívását, és B többet tud, mint a feladata. Alapesetben nem kéne, hogy egy osztálynak legyen ctor-ként működő init-je.

    Kicsit más jellegű lenne az a megoldás, ha B kap tisztán virtuális read() és write() függvényeket, és azokat override-olja D. Viszont read()-et nem hívhatod ctorból, úgyhogy ez nem működik.

  • jattila48

    aktív tag

    válasz jattila48 #3064 üzenetére

    Arra minden esetre jó volt ez az eszmefuttatás, hogy legalább magamat sikerült meggyőzni (remélem titeket is. Vagy nem?) a megoldásom helyességéről. Vagyis ha egy osztályból csak származtatni lehet és őt magát nem lehet példányosítani, akkor nem koncepcionális hiba az osztály kétfázisú inicializálása protected init tfv.-nyel. Sőt úgy gondolom, hogy az ilyen osztályból származtatott osztály teljes értékű RAII kezelése (a ctor. foglalja le a példány "létezéséhez"/működéséhez szükséges erőforrásokat, a dtor szabadítja fel azokat) adott esetben (ha az ősosztálynak szüksége van az erőforrásokra) nem is valósítható meg másként. A free/static fv.-ek alkalmazása szükség szerűen megsérti a RAII koncepciót, hiszen már az objektum létrejötte előtt le kell foglalnia az erőforrásokat. Ezen az sem segít (sőt...), ha a felszabadítást már a dtor végzi.

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