从c++中的派生类调用未在基类上定义的成员函数是否安全
is it safe to calling a member function not defined on the base class from of a derived class in c++?
我读到了关于委派的文章,我希望能够在基类中调用任何函数作为参数传递,具体取决于事件,因此,如果例如我有一个解析器对象,并且我希望根据找到的令牌从另一个对象分配要调用的方法。我按照下面的方式做了,它有效,但我不确定它是正确的方式还是便携的。
class base{
public:
typedef void (base::*methodPTR)();
methodPTR pfn;
void setMethod(methodPTR fn)
{
pfn = fn;
}
void run(){
if(pfn) (this->*pfn)();
}
};
class a : public base {
public:
};
class b : public base
{
a ob;
public:
void init()
{
//this function fn is not define neither in object "a" or "base"
//but still I can assign arbitrary member function just like I wanted
ob.setMethod(static_cast<base::methodPTR>(&b::fn));
}
void fn()
{
cout << "from class b!" << endl;
}
void test()
{
ob.run();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
b x;
x.init();
x.test();
return 0;
}
只要你确信你从未在一个对象上调用成员指针,而该对象实际上不是指针来源的类型之一(即你没有在base
上调用a::x
),那么你正在做的事情是安全的。
尝试这个问题的模板解决方案,在这个例子中,我确信使用正确的对象来调用正确的函数。我们可以在有映射对象和回调的情况下使用它,并且可能会根据某些条件调用它们。
//store objects vs callbacks
//you could replace int in map with some condition or key to invoke a callback
#include <iostream>
#include <map>
using namespace std;
template<class T>
class A {
protected:
void (T::*curr_f)();
private:
static std::map<int, std::map<T*,void (T::*)() > > callBacks;
public:
virtual void set(void (T::*f)()) {
curr_f = f;
cout<<"Set in A"<<endl;
T* obj = new T();
static int x = 0;
callBacks[++x][obj] = f;
// (obj->*curr_f)();
}
virtual void new_function() {cout<<"in A"<<endl;};
static void run()
{
for(typename std::map<int,std::map<T*,void (T::*)() > >::iterator itr = A<T>::callBacks.begin();
itr != A<T>::callBacks.end(); ++itr)
{
for(typename std::map<T*,void (T::*)() >::iterator itr2 = itr->second.begin();
itr2 != itr->second.end(); ++itr2)
{
((itr2->first)->*(itr2->second))();
}
}
}
};
template<class T>
std::map<int, std::map<T*,void (T::*)() > > A<T>::callBacks;
class B :public A<B> {
public:
void func() {
set(&B::new_function);
};
void new_function() {cout<<"in B"<<endl;};
};
class C:public A<C> {
public:
void func() {
set(&C::new_function);
};
void new_function() {cout<<"in C"<<endl;};
};
int main()
{
B obj1;
C obj2;
obj1.func();
obj2.func();
A<B>::run();
A<C>::run();
}
相关文章:
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- C++令牌定义成员
- 在没有类定义的标头中定义成员变量
- 如何在类的构造函数中定义成员向量的大小
- 如何在C++中动态定义成员函数
- C++ Boost.Serialization - 用户定义成员的非侵入式序列化
- C++类 - 使用公共变量并在类外定义成员函数
- G++ - 对已定义成员函数的未定义引用
- 在哪里以及如何定义成员变量?在头文件还是实现文件中?
- 是否可以修改STL并自定义成员函数
- 从 boost::mpl:vector 类型列表中定义成员变量
- 在构造对象时定义成员函数
- 为什么定义成员函数指针变量需要类名
- 复制构造函数中的 C++ 用户定义成员
- 如何根据类参数定义成员类运算符
- 使用指向未定义成员函数的指针时的未定义引用
- 如何在运行时定义成员数组大小
- C++-在模板类之外但在头中定义成员函数
- c++在不知道对象类型的情况下定义成员函数指针
- 在特定偏移量中定义成员的结构