c++ - Creating and using func pointer to method of friend class -
i have 2 classes:
enum class enumtype { typ1, typ2, }; class { private: rettype func1(arg1type, arg2type, arg3type); rettype func2(arg1type, arg2type, arg3type); public: a(); rettype func(enumtype, arg1type, arg2type, arg3type); } class b { private: arg1type a; arg2type b; arg3type c; public: int functionfromb(enumtype); }
so primary use this:
int b::functionfromb(enumtype x) { a* objecta; for(int i=0; i<whatever; i++) { objecta->func(x, a+i, b+(2*i), c+(3*i)); } } rettype a::func(enumtype x, arg1type a, arg2type b, arg3type c) { switch(x) { case enumtype::typ1: return func1(a, b, c); case enumtype::typ2: return func2(a, b, c); default: return func1(a, b, c); } }
unfortunately not want run switch every loop , thought this:
- in class write "friend class b"
- remove a::func()
- make function ptr in b::functionfromb()
- make switch in b::functionfromb(), initializes mentioned function ptr either a::func1 or a::func2. switch resemble 1 in a::func()
- instead of running objecta->func(x, a, b, c), run objecta->functionptr(a, b, c)
how this? tried std::function, don't know how declare/initialize/call make work.
edit:
i've edited functionfromb, because i've skipped 1 important part -> func called in loop different args.
edit2:
given , have answer saying how c-style function ptr, yet want make work std::function. made (note class b , enum same):
class { private: rettype func1(arg1type, arg2type, arg3type); rettype func2(arg1type, arg2type, arg3type); public: a(); typedef std::function<rettype(arg1type, arg2type, arg3type)> funcptr; } int b::functionfromb(enumtype typeb) { a* objecta; a::funcptr func = nullptr; switch(type) { case enumtype::typ2: func = std::bind(&a::func2, objecta, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); break; case enumtype::typ2: default: func = std::bind(&a::func1, objecta, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); break; } for(int i=0; i<whatever; i++) func(a+i, b+(2*i), c+(3*i)); }
and guess, works. if finds error in here or better way, please tell me ;)
could use unscoped enum enumtype?
enum enumtype { enumtyp1, enumtyp2, enumtypmax };
if option, compiler offers free conversion int : enumtyp1 -> 0
, enumtyp2 -> 1
,enumtypmax -> 2
(per 3.9.2 § 10 the value of enumerator or object of unscoped enumeration type converted integer integral promotion)
the values guaranteed per 3.9.2 §2 the identifiers in enumerator-list declared constants, , can appear wherever constants required. enumeratordefinition = gives associated enumerator value indicated constant-expression. if first enumerator has no initializer, value of corresponding constant zero. enumerator-definition without initializer gives enumerator value obtained increasing value of previous enumerator one.
enum { a, b, c=0 }; enum { d, e, f=e+2 };
defines a, c, , d zero, b , e 1, , f 3.
you build static array of methods in , use direct array index should simpler switch :
enum enumtype { enumtyp1, enumtyp2, enummax }; class { private: typedef rettype (__thiscall a::*funcx)(arg1type,arg2type,arg3type); rettype func1(arg1type, arg2type, arg3type); rettype func2(arg1type, arg2type, arg3type); static funcx fp[enummax]; public: a(); rettype func(enumtype, arg1type, arg2type, arg3type); }; class b { private: arg1type a; arg2type b; arg3type c; public: int functionfromb(enumtype); }; int b::functionfromb(enumtype x) { a* objecta; for(int i=0; i<whatever; i++) { objecta->func(x, a+i, b+(2*i), c+(3*i)); } return whatever; } rettype a::func(enumtype x, arg1type a, arg2type b, arg3type c) { funcx f = a::fp[x]; return (this->*fp[x])(a, b, c); } a::funcx a::fp[enummax] = { &a::func1, &a::func2 };
alternatively, directly pointer in b::functionfromb
, directly call repeatedly :
enum enumtype { enumtyp1, enumtyp2, enummax }; class { public: typedef rettype (__thiscall a::*funcx)(arg1type,arg2type,arg3type); private: rettype func1(arg1type, arg2type, arg3type); rettype func2(arg1type, arg2type, arg3type); static funcx fp[enummax]; public: a(); friend class b; }; class b { private: arg1type a; arg2type b; arg3type c; a::funcx getfunc(enumtype); public: int functionfromb(enumtype); }; a::funcx b::getfunc(enumtype x){ return a::fp[x]; } int b::functionfromb(enumtype x) { a* objecta; a::funcx funcptr = getfunc(x); for(int i=0; i<whatever; i++) { (objecta->*funcptr)(a+i, b+(2*i), c+(3*i)); } return whatever; } a::funcx a::fp[enummax] = { &a::func1, &a::func2 };
in latter case, avoid declaring array of methods in a, stick scoped enum enumtype , use switch once per call b::functionfromb
:
a::funcx b::getfunc(enumtype x){ switch (x) { case enumtype::typ1: return &a::func1; case enumtype::typ2: return &a::func2; case default: return &a::func1; } }
Comments
Post a Comment