预备知识
C++函数指针
c++中普通函数和类成员函数的声明和使用方式都不一样。
声明:类成员函数在声明的时候需要指定是哪一个类,
调用:类普通成员函数调用的时候需要明确是该类的具体实例,类静态成员函数需要指定该类。
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void normalFunc() { // 普通函数
cout << "this is a normal function!" << endl;
}
class A {
public:
static void staticFunc() { // 静态成员函数
cout << "this is a static function!" << endl;
}
void memFunc() { // 普通成员函数
cout << "this is a member function!" << endl;
}
};
int main()
{
// 普通函数和类成员函数的指针声明
typedef void(*funcp)();
typedef void(A::*memfuncp)();
funcp f1 = normalFunc;
memfuncp f2 = &A::memFunc;
funcp f3 = A::staticFunc;
f1();
// 普通函数和类成员函数的调用方式
A a; // 声明类的具体实例
(a.*f2)();
f3();
return 0;
}
C++的动态类型判断
无参委托函数
没有参数的委托函数的构造
1. 函数指针类实现
由于普通函数和成员函数的调用方式等存在差异,所以需要实现两种类继承一个抽象委托类。
- 抽象类:
实现动态类型判断的函数
实现函数调用invoke - 普通函数:设计普通成员函数指针成员变量,重写相关方法。
- 成员函数:用模板实现,设计模板类实例和模板成员函数指针变量,重写相关方法。
2. 统一委托函数生成接口实现
重载newDelegate函数,根据参数类型创建不同的委托函数。
3. 委托类实现
有一个存储函数委托指针类的列表
重载了 += 表示向这个委托注册一个函数指针,这个方法会自动判重,如果重复了就不会向里面添加。
重载了 -= 表示向这个委托注销一个函数指针,如果这个函数指针不存在就什么也不执行。
重载了 () 表示当作函数调用启动这个委托,内部就是将所有函数指针指向的函数都运行一遍。
无参无返回值函数指针类实现代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
// 抽象委托类
class IDelegate
{
public:
virtual ~IDelegate(){};
// 进行函数调用
virtual void invoke() = 0;
// 使用RTTI进行类型判断
virtual bool isType(const type_info &_type) = 0;
virtual bool compare(IDelegate *_delegate) const = 0; // 一般加下划线表示成员变量
};
// 能注册普通函数的委托类
class normalFunc : public IDelegate
{
public:
// 定义无参函数指针
typedef void (*normalFuncp)();
normalFunc(normalFuncp func) : f(func) {}
virtual void invoke()
{
f();
}
virtual bool isType(const std::type_info &_type) { return typeid(normalFunc) == _type; }
virtual bool compare(IDelegate *_delegate) const
{
// 判断动态类型是否一致
if (_delegate == 0 || !_delegate->isType(typeid(normalFunc)))
return false;
normalFunc *cast = dynamic_cast<normalFunc *>(_delegate);
return cast->f == f;
}
private:
normalFuncp f;
};
// 能注册成员函数的委托类
template <typename T>
class memFunc : public IDelegate
{
public:
typedef void (T::*memFuncp)();
memFunc(T *_object, memFuncp func) : object(_object), f(func) {}
virtual void invoke()
{
(object->*f)();
}
virtual bool isType(const std::type_info &_type) { return typeid(memFunc<T>) == _type; }
virtual bool compare(IDelegate *_delegate) const
{
// 判断动态类型是否一致
if (_delegate == 0 || !_delegate->isType(typeid(memFunc<T>)))
return false;
memFunc<T> *cast = dynamic_cast<memFunc<T> *>(_delegate);
return cast->object == object && cast->f == f;
}
private:
T *object;
memFuncp f;
};
// 统一的接口生成函数指针对象
IDelegate *newDelegate(void (*f)())
{
return new normalFunc(f);
}
template <typename T>
IDelegate *newDelegate(T *object, void(T::*f)())
{
return new memFunc<T>(object, f);
}
// example
class A
{
public:
void func()
{
cout << "member func of A." << endl;
}
};
void func()
{
cout << "normal func." << endl;
}
int main()
{
IDelegate *nf = newDelegate(func);
A *a;
IDelegate *mf = newDelegate<A>(a,&A::func);
nf->invoke();
mf->invoke();
return 0;
}
委托类实现代码
// 委托类
class CMultiDelegate
{
public:
typedef std::list<IDelegate*> ListDelegate;
typedef ListDelegate::iterator ListDelegateIterator;
typedef ListDelegate::const_iterator ConstListDelegateIterator;
CMultiDelegate () { }
~CMultiDelegate () { clear(); }
bool empty() const
{
for (ConstListDelegateIterator iter = mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
{
if (*iter) return false;
}
return true;
}
void clear()
{
for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
{
if (*iter)
{
delete (*iter);
(*iter) = 0;
}
}
}
CMultiDelegate& operator+=(IDelegate* _delegate)
{
for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
{
if ((*iter) && (*iter)->compare(_delegate))
{
delete _delegate;
return *this;
}
}
mListDelegates.push_back(_delegate);
return *this;
}
CMultiDelegate& operator-=(IDelegate* _delegate)
{
for (ListDelegateIterator iter=mListDelegates.begin(); iter!=mListDelegates.end(); ++iter)
{
if ((*iter) && (*iter)->compare(_delegate))
{
if ((*iter) != _delegate) delete (*iter);
(*iter) = 0;
break;
}
}
delete _delegate;
return *this;
}
void operator()( )
{
ListDelegateIterator iter = mListDelegates.begin();
while (iter != mListDelegates.end())
{
if (0 == (*iter))
{
iter = mListDelegates.erase(iter);
}
else
{
(*iter)->invoke();
++iter;
}
}
}
private:
CMultiDelegate (const CMultiDelegate& _event);
CMultiDelegate& operator=(const CMultiDelegate& _event);
private:
ListDelegate mListDelegates;
};
// example
class A
{
public:
void func()
{
cout << "member func of A." << endl;
}
};
void func()
{
cout << "normal func." << endl;
}
int main()
{
IDelegate *nf = newDelegate(func);
A *a;
IDelegate *mf = newDelegate<A>(a, &A::func);
CMultiDelegate s;
s+=nf;
s+=mf;
s();
s-=nf;
cout << "-----" << endl;
s();
return 0;
}