Hirdetés

Keresés

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

  • dobragab

    addikt

    válasz ToMmY_hun #3496 üzenetére

    Tuti ott leszek, már egy hónapja arra készülünk :DD Talán valami pólót is nyomtatunk.

    (Igen, "belsősök" súgták, hogy valamikor májusban jön.)

  • dobragab

    addikt

    válasz ToMmY_hun #3496 üzenetére

    Ez C++-ban is egy erős elv, előadáson a kolléga még el is mondta, hogy nem hívunk konstruktorban / destruktorban virtuális függvényt, vagy le fogják törni a kezed. Utána belerakja ezt a ZH-ba, én meg javíthatom. Komolyan, legszívesebben annak is megadtam volna a pontot, aki B::f-et írt.

    (#3492) sztanozs

    A genyaság nincs még kimaxolva, szerintem sosem lehet kimaxolni. Még facsarhatjuk belőle a sz@rt kicsit.

    (#3489) ToMmY_hun

    Konstruálás során ugye először az ősosztály példányosodik, és mivel az említett kódban annak a példányosítása során hívunk egy virtuális függvényt, ezért nem futhat le olyan objektumhoz tartozó definíciója, ami a hívás pillanatában nem is létezik.

    Ez a C++ megoldása a problémára, úgy definiálták a szabványban, hogy ilyen ne történhessen. Történhet viszont rosszabb.

    Minden konstruktor csak saját magáért felelős. Így az ősosztályok konstruktorát hívja (+ virtuális örökléses blablabla), majd beállítja a vptr-t a sajátjára, aztán meghívja a tagváltozók konstruktorát, majd lefut a törzs. Fikarcnyit sem foglalkozik azzal, hogy mi van alatta. Nem tud róla, ki származik le belőle. És mivel a vptr-t is majd ezek után állítja csak be a leszármazott a saját vptr-ére, a konstruktorban a vptr még nem a leszármazottéra mutat, hanem a sajátra.

    Egyébként a szabványban nincs benne sehol a vtable / vptr, nincs rögzítve, hogy úgy kell implementálni, de úgy érdemes. Sőt, a szabvány úgy lett kialakítva, ahogy a vtable-ös megoldások működnek.

    A szabványban volt még egy sor, amit nem részleteztetek. A tagváltozók konstruktorában is az a fv. fog hívódni, ami a hierarchiában "nincs lejjebb", azaz a saját vagy "feljebb" van.

    Ha a konstruktorban hívott f tisztán virtuális, akkor nem fog fordulni, mert a linker nem találja meg a függvényt. Tisztán virtuális függvény lehet definiálva is, ez most mellékszál. Itt nem kell a vtable-höz nyúlni, mert nyilvánvaló, melyik típusnak a függvényét kell hívni. Ha viszont nem maga hívja meg, hanem közvetve egy olyan függvény, ami nem tudja, pontosan milyen típust is kapott, akkor muszáj lesz a vtable-ben megnéznie. Akár tagváltozó konstruktorában is, mint írtam. Tadamm, így lehet tisztán virtuális függvényt meghívni.

    #include <iostream>

    class A;

    struct member
    {
    A * a;
    member(A* a);
    };

    struct A
    {
    member m = this;
    A() { }
    virtual void f() = 0;
    virtual ~A() {}
    };

    member::member(A * a) : a(a)
    {
    a->f();
    }

    struct B : public A
    {
    void f() { std::cout << "B::f\n";}
    };

    int main()
    {
    B b;
    return 0;
    }

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