c++ - Why is the wrong function being executed? -
i ran confusing situation today i'm hoping can explain me.
i have c++ program 4 classes:
- a
base
class acts common interface, - an
enroll
class, subclassesbase
, has pure virtualenroll()
method, - a
verify
class, subclassesbase
, has pure virtualverify()
method, - a
both
class subclasses bothenroll
,verify
, provides implementationsenroll()
,verify()
like so:
class base { public: base () { } virtual ~base () { } }; class enroll : public virtual base { public: virtual ~enroll () { } virtual void enroll () = 0; }; class verify : public virtual base { public: virtual ~verify () { } virtual void verify () = 0; }; class both : public enroll, public verify { public: virtual ~both () { } virtual void enroll () { printf ("enrolling.\n"); } virtual void verify () { printf ("verifying.\n"); } };
instances of both
instantiated in non-member function, creates new both
, returns pointer:
both* createinstanceofboth () { return new both(); }
finally, there's registry
class acts enroll
/verify
factory. uses pair of function pointers createinstanceofboth()
function provide instance of enroll
or verify
:
typedef enroll* (*enrollgenerator) (); typedef verify* (*verifygenerator) (); class registry { public: registry () { enrollgenerator = (enrollgenerator)&createinstanceofboth; verifygenerator = (verifygenerator)&createinstanceofboth; } enroll* getenroll () { return enrollgenerator (); } verify* getverify () { return verifygenerator (); } enrollgenerator enrollgenerator; verifygenerator verifygenerator; };
and here's problem. when call getenroll()
on registry
object , invoke enroll()
on object that's returned, see proper, expected output: enrolling.
. when call getverify()
, invoke verify()
on object that's returned, the enroll()
method executed again!
code:
int main () { registry registry; enroll *enroller; verify *verifier; enroller = registry.getenroll (); verifier = registry.getverify (); enroller->enroll (); verifier->verify (); return 0; }
output:
enrolling. enrolling.
i've noticed if change order of enroll
, verify
in declaration of both
class (class both : public verify, public enroll {...}
), opposite effect happen:
verifying. verifying.
i've identified workaround in which, instead of using single createinstanceofboth()
function create enroll
, verify
objects, use 2 differently named functions same body different return types:
enroll* createinstanceofenroll () { return new both(); } verify* createinstanceofverify () { return new both(); }
then, in registry class, create function pointers these functions instead:
registry () { enrollgenerator = &createinstanceofenroll; verifygenerator = &createinstanceofverify; }
when run program now, expected output:
enrolling. verifying.
my question this: why doesn't first way of doing work? suspect has casting createinstanceofboth()
function pointer different return type, don't understand what's happening. i'm fine using workaround @ moment, i'm curious: there way of doing single createinstanceofboth()
function instead of having use 2 identical functions different return types?
to save time , hassle of putting compilable example, i've posted code https://gist.github.com/833304 download.
that function pointer cast (treating function returning both*
returning verify*
or enroll*
) incorrect; multiple inheritance, different base classes within object not start @ beginning of object. function pointer cast not doing offsetting operation required derived-to-base pointer casts both*
base pointer types.
you can have single createinstanceofboth
function, need return both*
; code calls derived-to-base cast result.
Comments
Post a Comment