首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

小弟我想在一个对象里调用另一个对象的方法,但是这两个对象之间最好不要有什么太多的关系

2012-02-19 
我想在一个对象里调用另一个对象的方法,但是这两个对象之间最好不要有什么太多的关系。/*我想在一个对象里

我想在一个对象里调用另一个对象的方法,但是这两个对象之间最好不要有什么太多的关系。
/*
我想在一个对象里调用另一个对象的方法,但是这两个对象之间最好不要有什么太多的关系。下面代码基本可以实现我的要求,但是另外生成了两个新的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指针实际所指来释放空间.
[解决办法]
蛮有趣的代码.
标准库应该有提供类似的代码,不过功能稍差,这个功能就比较强.
感觉不要那个基类不是更好点?

回答楼上:
继承的标配就是虚拟析构函数.选配是普通的,普通的缺少以下能力:
不能调用子类的析构函数,因此子类不能有需要自定义释放掉的资源(一般是指针成员).

热点排行