Pointers to Member Functions
isocpp FAQ Pointers to Member Functions ¶ Δ
Example
下面的例子展示了pointers to Member Functions的用法。
sourcemaking Adapter in C++: External Polymorphism
- Specify the new desired interface
- Design a "wrapper" class that can "impedance match" the old to the new
- The client uses (is coupled to) the new interface
- The adapter/wrapper "maps" to the legacy implementation
#ifdef _MSC_VER
#include "stdafx.h"
#endif
#include <iostream>
using namespace std;
class ExecuteInterface
{
public:
// 1. Specify the new interface
virtual ~ExecuteInterface()
{
}
virtual void execute() = 0;
};
// 2. Design a "wrapper" or "adapter" class
template<class TYPE>
class ExecuteAdapter: public ExecuteInterface
{
public:
ExecuteAdapter(TYPE *o, void (TYPE::*m)())
{
object = o;
method = m;
}
~ExecuteAdapter()
{
delete object;
}
// 4. The adapter/wrapper "maps" the new to the legacy implementation
void execute()
{ /* the new */
(object->*method)();
}
private:
TYPE *object; // ptr-to-object attribute
void (TYPE::*method)(); /* the old */ // ptr-to-member-function attribute
};
// The old: three totally incompatible classes
// no common base class,
class Fea
{
public:
// no hope of polymorphism
~Fea()
{
cout << "Fea::dtor" << endl;
}
void doThis()
{
cout << "Fea::doThis()" << endl;
}
};
class Feye
{
public:
~Feye()
{
cout << "Feye::dtor" << endl;
}
void doThat()
{
cout << "Feye::doThat()" << endl;
}
};
class Pheau
{
public:
~Pheau()
{
cout << "Pheau::dtor" << endl;
}
void doTheOther()
{
cout << "Pheau::doTheOther()" << endl;
}
};
/* the new is returned */
ExecuteInterface** initialize()
{
ExecuteInterface **array = new ExecuteInterface*[3];
/* the old is below */
array[0] = new ExecuteAdapter<Fea>(new Fea(), &Fea::doThis);
array[1] = new ExecuteAdapter<Feye>(new Feye(), &Feye::doThat);
array[2] = new ExecuteAdapter<Pheau>(new Pheau(), &Pheau::doTheOther);
return array;
}
int main()
{
ExecuteInterface **objects = initialize();
for (int i = 0; i < 3; i++)
{
objects[i]->execute();
}
// 3. Client uses the new (polymporphism)
for (int i = 0; i < 3; i++)
{
delete objects[i];
}
delete objects;
return 0;
}
// g++ -Wall -pedantic test.cpp && ./a.out
NOTE:
1、上面是修正版,原文的版本是存在错误的
2、运行结果如下:
fax & print something print internal printJob
3、上述例子是不及 informit Design Patterns with Signature-Based Polymorphism: A C++ Approach # External Polymorphism 的
4、上述例子运用了:
a、generic invoke、call pointer to member function
b、OOP interface + template implementation
Template pointer to member function
#define XS_TYPE_TRAITS_DEF_HAS_PUBLIC_METHOD( _N_, _F_ ) \
template< typename _T_, typename _R_, typename ... _A_ > \
class _N_ \
{ \
private: \
\
struct _Y { char _[ 1 ]; }; \
struct _N { char _[ 2 ]; }; \
\
template< typename _U_, _U_ > struct _S; \
\
template< typename _C_ > static _Y & _T( _S< _R_ ( _C_::* )( _A_ ... ), ( &_C_::_F_ ) > * ); \
template< typename _C_ > static _N & _T( ... ); \
\
public: \
\
enum { value = sizeof( _T< _T_ >( nullptr ) ) == sizeof( _Y ) }; \
}
2、cppreference std::is_member_function_pointer
#include<type_traits>
template<class T>
struct is_member_function_pointer_helper: std::false_type
{
};
template<class T, class U>
struct is_member_function_pointer_helper<T U::*> : std::is_function<T>
{
};
template<class T>
struct is_member_function_pointer: is_member_function_pointer_helper<typename std::remove_cv<T>::type>
{
};
3、sourcemaking Adapter in C++: External Polymorphism
4、Check if a class has a member function of a given signature # A
template<typename T>
struct HasUsedMemoryMethod
{
template<typename U, size_t (U::*)() const> struct SFINAE {};
template<typename U> static char Test(SFINAE<U, &U::used_memory>*);
template<typename U> static int Test(...);
static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};
template<typename TMap>
void ReportMemUsage(const TMap& m, std::true_type)
{
// We may call used_memory() on m here.
}
template<typename TMap>
void ReportMemUsage(const TMap&, std::false_type)
{
}
template<typename TMap>
void ReportMemUsage(const TMap& m)
{
ReportMemUsage(m,
std::integral_constant<bool, HasUsedMemoryMethod<TMap>::Has>());
}
这篇文章,收录在了Detection-idiom
章节了。