我想在一个对象里调用另一个对象的方法,但是这两个对象之间最好不要有什么太多的关系。
/*
我想在一个对象里调用另一个对象的方法,但是这两个对象之间最好不要有什么太多的关系。下面代码基本可以实现我的要求,但是另外生成了两个新的class 代码。
不知有没有另好的方法呢?
最好只要一个新CLASS就好了,毕竟中间多了一层虚拟函数的调用,有点浪费啊~。
*/
//代码可直接运行
#include <iostream>
template <class PARAM>
struct BaseFunctionClass
{
virtual bool Call(PARAM param) = 0;
};
template <class BASE_CLASS,class PARAM>
class FunctionClass : public BaseFunctionClass <PARAM>
{
public:
typedef bool (BASE_CLASS::*CLASS_FUNCTION)(PARAM);
FunctionClass (BASE_CLASS *the_pointer, CLASS_FUNCTION method) : class_pointer(the_pointer),class_method(method) {}
virtual bool Call(PARAM param) { return (class_pointer-> *class_method)(param); }
private:
BASE_CLASS *class_pointer;
CLASS_FUNCTION class_method;
};
using namespace std;
class CT1
{
public:
CT1 () : m_value(9090) {}
bool ShowMe(int a) { cout < < "a= " < < a < < " value= " < < m_value < < endl; return true; }
int m_value;
};
int main( void )
{
CT1 ctct;
//保存该对象的方法
BaseFunctionClass <int> *fun = new FunctionClass <CT1,int> ( &ctct, &CT1::ShowMe );
ctct.m_value = 7894056;
//试着调用
fun-> Call(100);
return 0;
}
[解决办法]
这个问题的标准解法应该如lz所写的,毕竟这是类型安全的,但是无论空间还是时间的浪费也是明显的,其实如果想简单点也根本不用这么麻烦,我的方法是牺牲一些类型安全,但是时间和空间几乎没有损失,也符合lz只要一个类的要求,代码如下:
// 对外公布的辅助类
struct ClassFunHelper
{
typedef bool (ClassFunHelper::*PFun)();
typedef bool (ClassFunHelper::*PFunint)(int);
typedef bool (ClassFunHelper::*PFunintint)(int, int);
PFun pfun;
PFunint pfunint;
PFunintint pfunintint;
ClassFunHelper* pObj;
};
// 内部的调用类,不公开
class CA
{
public:
CA () {}
bool Show0() { cout < < "CA::Show " < < endl; return true; }
bool Show1(int a) { cout < < "CA::Show1 " < < " a= " < < a < < " value= " < < m_value < < endl; return true; }
virtual bool Show2(int a, int b) { cout < < "CA::Show2 " < < " a= " < < a < < " b= " < < b < < " value= " < < m_value < < endl; return true; }
int m_value;
};
class CB : public CA
{
public:
CB () {}
bool Show0() { cout < < "CB::Show " < < endl; return true; }
bool Show1(int a) { cout < < "CB::Show1 " < < " a= " < < a < < " value= " < < m_value < < endl; return true; }
virtual bool Show2(int a, int b) { cout < < "CB::Show2 " < < " a= " < < a < < " b= " < < b < < " value= " < < m_value < < endl; return true; }
};
class CAA
{
public:
CAA () {}
bool Show0() { cout < < "CAA::Show " < < endl; return true; }
bool Show1(int a) { cout < < "CAA::Show1 " < < " a= " < < a < < " value= " < < m_value < < endl; return true; }
virtual bool Show2(int a, int b) { cout < < "CAA::Show2 " < < " a= " < < a < < " b= " < < b < < " value= " < < m_value < < endl; return true; }
int m_value;
};
class CBB : public CAA
{
public:
CBB () {}
bool Show0() { cout < < "CBB::Show " < < endl; return true; }
bool Show1(int a) { cout < < "CBB::Show1 " < < " a= " < < a < < " value= " < < m_value < < endl; return true; }
virtual bool Show2(int a, int b) { cout < < "CBB::Show2 " < < " a= " < < a < < " b= " < < b < < " value= " < < m_value < < endl; return true; }
};
int main(int argc, char* argv[])
{
ClassFunHelper helper;
CA a;
a.m_value = 333;
helper.pObj = (ClassFunHelper*)&a;
helper.pfun = (ClassFunHelper::PFun)&CA::Show0;
((helper.pObj)-> *(helper.pfun))();
helper.pfunint = (ClassFunHelper::PFunint)&CA::Show1;
((helper.pObj)-> *(helper.pfunint))(100);
helper.pfunintint = (ClassFunHelper::PFunintint)&CA::Show2;
((helper.pObj)-> *(helper.pfunintint))(100, 200);
CB b;
b.m_value = 444;
helper.pObj = (ClassFunHelper*)&b;
helper.pfun = (ClassFunHelper::PFun)&CB::Show0;
((helper.pObj)-> *(helper.pfun))();
helper.pfunint = (ClassFunHelper::PFunint)&CB::Show1;
((helper.pObj)-> *(helper.pfunint))(100);
helper.pfunintint = (ClassFunHelper::PFunintint)&CB::Show2;
((helper.pObj)-> *(helper.pfunintint))(100, 200);
CAA aa;
aa.m_value = 555;
helper.pObj = (ClassFunHelper*)&aa;
helper.pfun = (ClassFunHelper::PFun)&CAA::Show0;
((helper.pObj)-> *(helper.pfun))();
helper.pfunint = (ClassFunHelper::PFunint)&CAA::Show1;
((helper.pObj)-> *(helper.pfunint))(100);
helper.pfunintint = (ClassFunHelper::PFunintint)&CAA::Show2;
((helper.pObj)-> *(helper.pfunintint))(100, 200);
CBB bb;
bb.m_value = 666;
helper.pObj = (ClassFunHelper*)&bb;
helper.pfun = (ClassFunHelper::PFun)&CBB::Show0;
((helper.pObj)-> *(helper.pfun))();
helper.pfunint = (ClassFunHelper::PFunint)&CBB::Show1;
((helper.pObj)-> *(helper.pfunint))(100);
helper.pfunintint = (ClassFunHelper::PFunintint)&CBB::Show2;
((helper.pObj)-> *(helper.pfunintint))(100, 200);
return 0;
}
[解决办法]
上面的BaseFunctionClass 这样的话需要设置析构函数吗?
如果要设置一定要用虚拟析构函数吗?为什么?
---------------------
理论上,有new就要有delete
所以要用析构.
为什么虚拟析构?
因为这样根据this指针实际所指来释放空间.
[解决办法]
蛮有趣的代码.
标准库应该有提供类似的代码,不过功能稍差,这个功能就比较强.
感觉不要那个基类不是更好点?
回答楼上:
继承的标配就是虚拟析构函数.选配是普通的,普通的缺少以下能力:
不能调用子类的析构函数,因此子类不能有需要自定义释放掉的资源(一般是指针成员).