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

  • jattila48

    aktív tag

    Sziasztok!

    Egy olyan pimpl megvalósítást szeretnék csinálni, amiben nincs a handle osztály (ez tartalmazza a pimpl pointert) tfv.-einek hívásából adódó forward hívás overhead. "Normálisan" a handle osztály tfv.-ei csak egy forwardolást csinálnak a body osztály (ebben van az implementáció) tfv.-einek hívásával pimpl->f() formában. Ezt az overheadet akarom elkerülni, vagyis a body osztály tfv.-eit közvetlenül akarom hívni.
    Példa:

    //pimpl_proba.cpp file
    #include "handle_class.h"

    int main(int argc,char *argv[])
    {
    HandleClass hc;
    BodyClass *pimpl=hc.pimpl;
    int n=0;
    n=hc.f(1);
    int (BodyClass::*ff)(int)=HandleClass::mfp;
    n=(pimpl->*ff)(2);
    n=1;
    return 0;
    }

    //handle_class.h file
    #ifndef _HANDLE_CLASS_
    #define _HANDLE_CLASS_
    class BodyClass;
    struct HandleClass{
    HandleClass();
    ~HandleClass();
    BodyClass *pimpl;
    int f(int n);
    static int (BodyClass::*mfp)(int);
    };
    #endif

    //body_class.h file
    #ifndef _BODY_CLASS_
    #define _BODY_CLASS_
    class BodyClass{
    public:
    BodyClass();
    int f(int);
    private:
    int a;
    };
    #endif

    //handle_class.cpp file
    #include "handle_class.h"
    #include "body_class.h"
    HandleClass::HandleClass():pimpl(new BodyClass()){}
    HandleClass::~HandleClass(){delete pimpl;}
    int HandleClass::f(int n){
    return pimpl->f(n);
    }
    int (BodyClass::*HandleClass::mfp)(int)=&BodyClass::f;

    //body_class.cpp file
    #include "body_class.h"
    BodyClass::BodyClass():a(5){}
    int BodyClass::f(int n){
    return a+n;
    }

    A pimpl_proba.cpp fájl nem függ a body_class.h fájltól, vagyis ha a BodyClass-ban megváltozik az implementáció, nem kell újrafordítani a pimpl_proba.cpp-t. Azonban az n=hc.f(1); fv. hívás a return pimpl->f(n); fv. hívással két fv. hívást eredményez, amit szeretnék elkerülni. Ezért a HandleClass osztálynak van egy statikus BodyClass tfv.-re mutató member function pointere, ami a BodyClass f tfv.-re mutat. Az n=(pimpl->*ff)(2); utasítás közvetlenül ezen keresztül hívja meg a BodyClass f tfv.-ét, és így megspórolok egy forwarding fv. hívást (csak a debuggolás miatt lett több sorra szedve). Ez így lefordul VS2012 alatt, azonban access violation-nel elszáll. Belenéztem a lefordított assembly kódba, és szerintem hibás amit generál,és részben "fölöslegesnek" tűnik. Ugyanakkor gcc-vel simán lefordul és fut. Bár a gcc is mintha "fölösleges" kódot generálna a közvetlen hívás előtt (talán this pointer igazítás, virtuális tábla keresés?). Ezt a módszert már használtam nagyobb programban is, ott a VS is jól fordította és a "fölösleges" kódnak sem láttam nyomát.
    Kérdés: mi lehet a baj?
    A válaszokat előre is köszönöm, de kérem, aki hozzászól, a lényegre koncentráljon, ne arra hogy minek ez nekem, a pimpl miért nem private, és miért nem unique_ptr, stb.

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