maly Temat założony przez niniejszego użytkownika |
[C++] Implementacja delegata » 2014-03-19 08:11:47 Próbuję zaimplementować prostego delegata i trafiłem na małą przeszkodę, o ile wywołanie bezpośrednio metod klasy Test nie sprawia większych problemów to dostęp do metod klasy Base nie jest możliwy bez jawnego wskazanie zasięgu Ptr < Test, void( Test::* )( int, float ) > ptr2( Testobject, & Test::Base::f ); więc mam pytanie co zrobić żeby można było tak Ptr < Test, void( Test::* )( int, float ) > ptr2( Testobject, & Test::f ); .
#include <iostream>
class Base { public: void f( int a, float b ) { std::cout << "a = " << a << " b = " << b << std::endl; } };
class Test : public Base { public: void f( int a ) { std::cout << "a = " << a << std::endl; } };
template < typename Object, typename Func > class Ptr { Object mObject; Func mFunc; public: Ptr( Object o, Func f ) : mObject( o ) , mFunc( f ) { } template < typename A > void operator ()( A a ) { ( mObject.* mFunc )( a ); } template < typename A, typename B > void operator ()( A a, B b ) { ( mObject.* mFunc )( a, b ); } };
int main() { Test Testobject; Ptr < Test, void( Test::* )( int ) > ptr1( Testobject, & Test::f ); ptr1( 1 ); Ptr < Test, void( Test::* )( int, float ) > ptr2( Testobject, & Test::f ); ptr2( 2, 3.456f ); return 0; } |
|
DejaVu |
» 2014-03-19 09:21:50 Użyj biblioteki FastDelegate zamiast wymyślać koło na nowo. Druga opcja to użyć standardu C++11, ale np. w Visual C++ 2012 nie ma jeszcze wsparcia delegatów na metody. |
|
maly Temat założony przez niniejszego użytkownika |
» 2014-03-19 09:40:09 |
|
DejaVu |
» 2014-03-19 12:06:09 #include <iostream>
class Base { public: void f( int a, float b ) { std::cout << "a = " << a << " b = " << b << std::endl; } void g( int a, float b ) { std::cout << "a = " << a << " b = " << b << std::endl; } };
class Test : public Base { public: void f( int a ) { std::cout << "a = " << a << std::endl; } };
template < typename Object, typename Func > class Ptr { Object mObject; Func mFunc; public: Ptr( Object o, Func f ) : mObject( o ) , mFunc( f ) { } template < typename A > void operator ()( A a ) { ( mObject.* mFunc )( a ); } template < typename A, typename B > void operator ()( A a, B b ) { ( mObject.* mFunc )( a, b ); } };
int main() { Test Testobject; Ptr < Test, void( Test::* )( int ) > ptr1( Testobject, & Test::f ); ptr1( 1 ); Ptr < Test, void( Test::* )( int, float ) > ptr2( Testobject, & Base::f ); ptr2( 2, 3.456f ); Ptr < Test, void( Test::* )( int, float ) > ptr3( Testobject, & Test::g ); ptr3( 2, 3.456f ); return 0; }
Generalnie chodzi o to, że chcesz pobrać adres do metody, która się tak samo nazywa w obu klasach, więc adres klasy bazowej jest przykryty w klasie pochodnej. Powyżej masz rozwiązanie swojego problemu. |
|
maly Temat założony przez niniejszego użytkownika |
» 2014-03-19 12:45:42 Ptr < Test, void( Test::* )( int, float ) > ptr2( Testobject, & Base::f );
To jest właśnie sposób którego próbuję się pozbyć.
Ptr < Test, void( Test::* )( int, float ) > ptr3( Testobject, & Test::g );
A to jest tylko ominięcie problemu.
Chodzi mi oto że gdyby metoda klasy Base::f( int a, float b ) przeniesiona została do klasy Test działało by to normalnie a teraz mimo że Test dziedziczy po Base to kompilator płacze że niewie co zrobić.
Ten problem wynika chyba bardziej z mojego nierozumienia dziedziczenia bo zawsze wydawało mi się że jeśli dziedziczę to posiadam... :) |
|
Monika90 |
» 2014-03-19 13:52:57 f w klasie Test zasłania f odziedziczone z klasy Base, jeżeli chcesz żeby f było przeciążone, to użyj deklaracji using. Przykład struct B { void f( int ); };
struct D : B { using B::f; void f( int, int ); };
A poza tym użyj boost.signals |
|
maly Temat założony przez niniejszego użytkownika |
» 2014-03-19 14:35:50 @Monika No ja pierdziu to było takie proste;). Dzięki. |
|
« 1 » |