Sender: roachcock (poor guy), email area: Programming
Standard C ++ simulation of delegate in. net
Mailing station: BBS shuimu Tsinghua station (Mon mar 18 21:11:30 2002)
Delegate is successfully implemented by using the partial and member templates of the template to reload the function call operator. You can bind a common function or an object and its member functions.
Compiled in cygnuwin,
Delegate does not support the use of multiple functions. However, it is very simple to derive a class from STD: list.
You can.
Some problems with cygun I used,
My_delegate D2 = my_delegate (T, & test: F );
^ If it is written as & T, it will cause internal errors in the compiler.
I used to write a program with blank lines. I am not going to post it on BBS. Just put it up.
Various call conventions under Win32 are annoying and not considered. However, it is troublesome to implement them,
No
// Test. cpp: defines the entry point for the console application.
//
# Include <stddef. h>
Template <class T>
// Function traits, used to extract the return type of the Function
Struct function_traits
{
};
Template <class RT>
Struct function_traits <RT (*) ()>
{
Typedef RT result_type;
};
Template <class RT, class at>
Struct function_traits <RT (*) (at)>
{
Typedef RT result_type;
Typedef at argument_type;
};
Template <class RT, class at1, class at2>
Struct function_traits <RT (*) (AT1, AT2)>
{
Typedef RT result_type;
Typedef AT1 first_argument_type;
Typedef at2 second_argument_type;
};
// Function traits, used to extract the return type of class member functions
Template <class RT, class ot>
Struct function_traits <RT (OT: *) ()>
{
Typedef ot object_type;
Typedef RT result_type;
};
Template <class RT, class ot, class at>
Struct function_traits <RT (OT: *) (at)>
{
Typedef ot object_type;
Typedef RT result_type;
Typedef at argument_type;
Typedef at first_argument_type;
};
Template <class RT, class ot, class at1, class at2>
Struct function_traits <RT (OT: *) (AT1, AT2)>
{
Typedef ot object_type;
Typedef RT result_type;
Typedef AT1 first_argument_type;
Typedef at2 second_argument_type;
};
// Convert a common function class to a type-compatible member function type of a specified class
Template <typename ot, typename PFT>
Struct to_member_function_pointer
{
};
Template <typename ot, typename RT>
Struct to_member_function_pointer <ot, RT (*) ()>
{
Typedef RT (OT: * type )();
};
Template <typename ot, typename RT, typename at>
Struct to_member_function_pointer <ot, RT (*) (at)>
{
Typedef RT (OT: * type) ();
};
Template <typename ot, typename RT, typename at1, typename at2>
Struct to_member_function_pointer <ot, RT (*) (AT1, AT2)>
{
Typedef RT (OT: * type) (AT1, AT2 );
};
Template <typename ot, typename RT, typename at1, typename at2, typename at3>
Struct to_member_function_pointer <ot, RT (*) (AT1, at2, at3)>
{
Typedef RT (OT: * type) (AT1, at2, at3 );
};
// Convert to const member function
Template <typename ot, typename PFT>
Struct to_const_member_function_pointer
{
};
Template <typename ot, typename RT>
Struct to_const_member_function_pointer <ot, RT (*) ()>
{
Typedef RT (OT: * type) () const;
};
Template <typename ot, typename RT, typename at>
Struct to_const_member_function_pointer <ot, RT (*) (at)>
{
Typedef RT (OT: * type) (at) const;
};
Template <typename ot, typename RT, typename at1, typename at2>
Struct to_const_member_function_pointer <ot, RT (*) (AT1, AT2)>
{
Typedef RT (OT: * type) (AT1, AT2) const;
};
Template <typename ot, typename RT, typename at1, typename at2, typename at3>
Struct to_const_member_function_pointer <ot, RT (*) (AT1, at2, at3)>
{
Typedef RT (OT: * type) (AT1, at2, at3) const;
};
// Implementation of Delegate
Template <typename PFT>
Class delegate
{
Class Object
{
} * M_pobject; // Object Pointer, which is a proxy object
Typedef typename to_member_function_pointer <object, PFt>: Type object_member_fuunction_pointer;
Union
{
PFT m_pf;
Object_member_function_pointer m_pmf;
}; // The combination of function pointers and member function pointers
Public:
Typedef typename function_traits <PFT>: result_type;
Delegate ()
{
M_pobject = NULL;
M_pf = NULL;
}
Delegate (pft pf)
{
Operator = (PF );
}
Template <typename ot>
Delegate (
Ot * pobject,
Typename to_member_function_pointer <ot, PFt>: Type PMF
)
{
M_pobject = reinterpret_cast <object *> (pobject );
M_pmf = * (reinterpret_cast <object_member_function_pointer *> (& PMF ));
}
Template <typename ot>
Delegate (
Ot & pobject,
Typename to_member_function_pointer <ot, PFt>: Type PMF
)
{
M_pobject = reinterpret_cast <object *> (& pobject );
M_pmf = * (reinterpret_cast <object_member_function_pointer *> (& PMF ));
}
Template <typename ot>
Delegate (
Const ot * pobject,
Typename to_const_member_function_pointer <ot, PFt>: Type PMF
)
{
M_pobject = const_cast <object *> (reinterpret_cast <object *> (pobject ));
M_pmf = * (reinterpret_cast <object_member_function_pointer *> (& PMF ));
}
Template <typename ot>
Delegate (
Const ot & pobject,
Typename to_const_member_function_pointer <ot, PFt>: Type PMF
)
{
M_pobject = const_cast <object *> (reinterpret_cast <object *> (& pobject ));
M_pmf = * (reinterpret_cast <object_member_function_pointer *> (& PMF ));
}
Delegate & operator = (pft pf)
{
M_pf = PF;
M_pobject = 0;
Return * this;
}
Template <int>
: No parameter is allowed in the GCC function template. Only a placeholder "int" can be passed.
Result_type operator ()()
{
If (m_pobject)
Return (m_pobject-> * m_pmf )();
Else
Return m_pf ();
}
Template <typename at>
Result_type operator ()(
At A1
)
{
If (m_pobject)
Return (m_pobject-> * m_pmf) (A1 );
Else
Return m_pf (A1 );
}
Template <typename at1, typename at2>
Result_type operator ()(
AT1 A1,
At2 A2
)
{
If (m_pobject)
Return (m_pobject-> * m_pmf) (a1, a2 );
Else
Return m_pf (a1, a2 );
}
Template <typename at1, typename at2, typename at3>
Result_type operator ()(
AT1 A1,
At2 A2,
At3 A3
)
{
If (m_pobject)
Return (m_pobject-> * m_pmf) (A1, A2, A3 );
Else
Return m_pf (A1, A2, A3 );
}
};
Int GF (INT)
{
Return 0;
}
Class Test
{
Public:
Int F (INT) {return 0 ;}
};
Typedef DeleGate <int (*) (INT)> my_delegate;
Int main ()
{
Test T;
My_delegate d1 = & GF; // Common Function
My_delegate D2 = my_delegate (T, & test: F); // object and class member functions
D1 (0); // call
D2 (2 );
}
--
No, no.