CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

请教高手......一个简单的包装类问题,头痛ing

楼主vivalite_wei()2004-12-04 08:49:14 在 C/C++ / C++ 语言 提问

我现在有一个Template的二元树class,而且只允许使用一个实例,却被要向里面插入2个不同的Class,我还不能改动二元树class的代码。  
   
  二元树一旦实例化了就只能接受实例化的Class了,要向里面插入2个Class我唯一想到的办法就是写一个包装类。  
   
  包装类的生明(file_system.hpp)是这样的:  
  enum   eContain_type{   None,   eFile,   eDirectory   };  
   
  class   Container   {  
  public:  
  Container(){}   //default   constructor  
          ~Container()   {}   //destructor  
  Init(eContain_type   eType);   //init.   function  
   
  private:  
          void   *Element;   //   我想用这个变量动态指向File或Directory类,可是不知道怎么写  
   
  };  
   
  包装类(file_system.cpp)的实现代码:  
  Container::Init(eContain_type   eType){  
  File   *tFile   =   new   File;  
  Directory   *tDirectory   =   new   Directory;  
   
  switch(eType){  
  case   eFile:  
  {Element   =   tFile;}  
  break;  
  case   eDirectory:  
  {Element   =   tDirectory;}  
  break;  
  case   None:  
  break;  
  default:  
  ;  
  }  
  }  
   
  我的Main.cpp里这样写的:  
  int   main(){  
  Container   CC;  
  CC.Init(eFile);  
  CC.Element->GetFileDirGroup();   //   GetFileDirGroup()是class   File里的一个方法  
   
  return   1;  
   
  }  
  编译时报错  
  error   C2227:   left   of   '->GetFileDirGroup'   must   point   to   class/struct/union  
  error   C2248:   'Element'   :   cannot   access   private   member   declared   in   class   'Container'  
                            file_system.hpp(24)   :   see   declaration   of   'Element'  
   
  ======  
  我的File和Directory都是普通的非Template类。  
  我不能用模板来做,因为模板最后使用时要实例化,两个类就是两种实例化的包装类实例。我不允许使用第二个二元树的实例,所以无法在同一个二元树实例里实现插入两个实例化的包装类。  
   
  我研究过空指针,可是不得要领。我想要是有可以根据输入动态指向不同实例的聪明指针就好了。  
   
  各位高手能给我点建议吗?  
  谢谢了!!!  
   
  (3天内结贴,保证全分奉送)  
  问题点数:100、回复次数:11Top

1 楼vivalite_wei()回复于 2004-12-04 09:03:18 得分 0

对了,刚才我忘了说了,那个File和Directory类都是已实现的类,我也动不得。  
  所以现在夹在已实现的类之间要做转换,很难受Top

2 楼dot99(又来混CSDN来了)回复于 2004-12-04 11:49:31 得分 60

CC.Element->GetFileDirGroup();   //   GetFileDirGroup()是class   File里的一个方法  
  ....  
  你的Element是个private,你怎么。。。。  
   
  暂时看到这个。。。。  
  Top

3 楼dot99(又来混CSDN来了)回复于 2004-12-04 12:04:13 得分 0

>>我研究过空指针,可是不得要领。我想要是有可以根据输入动态指向不同实例的聪明指针就好了。  
   
  什么是空指针,你是指void吗?  
  在这个思路上,你可以写个  
  struct   elem_st{  
      void   *   point_to_inst;  
      inst_category   cate;  
  };  
  pti用来指向你的instance  
  cate用来标识  
  container提供相应的select(根据cate),在运行时候进行cast  
  这样能满足你的要求  
  不过,这个有点。。。。。丑陋  
  而且还得注意该死的内存相关问题  
   
  其他方向上嘛~~~  
  提供个思路  
  多态,使用这个东东  
  问一个,你是指二元树不能修改,还是指插入的class不能修改  
  对于插入的class能修改:  
  给他们提供一个基类,其他的,慢慢解决吧~~  
   
  主要是时间不够咯。。。。。。。。老大逼吃饭~~  
  等下来继续回  
   
   
   
  Top

4 楼vivalite_wei()回复于 2004-12-04 12:37:41 得分 0

太感谢楼上了,我想过多态,可是我这个问题是二元树和插入的Class都不能修改,所以,唉......  
   
  您说的第一个方法我有点不太明白,能给小弟详细解一下吗,非常感谢!Top

5 楼imRainman(雨人)回复于 2004-12-04 13:07:06 得分 40

#include   <algorithm>  
  #include   <typeinfo>  
  #include   <exception>  
   
  #include   <iostream>  
  #include   <vector>  
   
  using   namespace   std   ;  
   
  class   CAnyType  
  {  
  protected   :  
  class   CObject  
  {  
  public   :  
  virtual   CObject*   Clone(   )   =   0   ;  
  virtual   const   std::type_info&   Type(   )   const   =   0   ;  
  virtual   const   std::type_info&   PointerType(   )   const   =   0   ;  
  }   *m_pObject   ;  
   
  template   <typename   TypeName>  
  class   CTheObject   :   public   CObject  
  {  
  public   :  
  TypeName   m_tElement   ;  
   
  public   :  
  CTheObject(const   TypeName   &object)   :  
        m_tElement(object)   {   }  
   
  virtual   CObject   *Clone(   )  
  {  
  return   new   CTheObject<TypeName>(m_tElement)   ;  
  }  
   
  virtual   const   std::type_info&   Type(   )   const  
  {  
  return   typeid(TypeName)   ;  
  }  
   
  virtual   const   std::type_info&   PointerType(   )   const  
  {  
  return   typeid(TypeName*)   ;  
  }  
  }   ;  
   
  public   :  
  CAnyType(   )   :    
        m_pObject(0)   {   }  
   
  template   <typename   TypeName>  
  CAnyType(const   TypeName&   object)   :  
  m_pObject(new   CTheObject<TypeName>(object))   {   }  
   
  CAnyType(const   CAnyType&   other)   :  
  m_pObject(other.m_pObject   ?   other.m_pObject->Clone(   )   :   0)   {   }  
   
  template   <typename   TypeName>  
  TypeName   &as(   )  
  {  
  #ifdef   _DEBUG  
  if   (m_pObject->Type(   )   !=   typeid(TypeName))   throw   std::exception("bad   cast")   ;  
  #endif  
  return   static_cast<CTheObject<TypeName>   *>(m_pObject)->m_tElement   ;  
  }  
   
  template   <typename   TypeName>  
  TypeName   &as(   )   const  
  {  
  #ifdef   _DEBUG  
  if   (m_pObject->Type(   )   !=   typeid(TypeName))   throw   std::exception("bad   cast")   ;  
  #endif  
  return   static_cast<CTheObject<TypeName>   *>(m_pObject)->m_tElement   ;  
  }  
   
  void   Swap(CAnyType&   rhs)  
  {  
  std::swap(m_pObject,   rhs.m_pObject)   ;  
  }  
   
  CAnyType   &operator   =(const   CAnyType&   rhs)  
  {  
  Swap(CAnyType(rhs))   ;  
  return   *this   ;  
  }  
   
  template   <typename   TypeName>  
  CAnyType   &operator   =(const   TypeName&   rhs)  
  {  
  Swap(CAnyType(rhs))   ;  
  return   *this   ;  
  }  
   
  const   std::type_info&   Type(   )   const  
  {  
  return   m_pObject   ?   m_pObject->Type(   )   :   typeid(void)   ;  
  }  
   
  const   std::type_info&   PointerType(   )   const  
  {  
  return   m_pObject   ?   m_pObject->PointerType(   )   :   typeid(void)   ;  
  }  
   
  public   :  
  ~CAnyType(   )  
  {  
  delete   m_pObject   ;  
  }  
  }   ;  
   
  class   CFile  
  {  
  public   :  
  void   GetFileDirGroup(   )   {   cout   <<   "CFile\n"   ;   }  
  }   ;  
   
  class   CDirectary  
  {  
  public   :  
  void   GetxxxxxxxGroup(   )   {   cout   <<   "CDirectary\n"   ;   }  
  }   ;  
   
  void   main(   )  
  {  
  vector<CAnyType>   v   ;  
   
  v.push_back(CFile(   ))   ;  
  v.push_back(CDirectary(   ))   ;  
   
  v[0].as<CFile>(   ).GetFileDirGroup(   )   ;  
  v[1].as<CDirectary>(   ).GetxxxxxxxGroup(   )   ;  
  }  
  Top

6 楼imRainman(雨人)回复于 2004-12-04 13:08:25 得分 0

最好在vc7.0以上编译。6.0上好像会有点儿语法的问题~Top

7 楼dot99(又来混CSDN来了)回复于 2004-12-04 13:24:51 得分 0

struct   classA_tag{};  
  struct   classB_tag{};  
   
  class   holder   {  
  public:  
      enum   ID_T   {   ID_classA,   ID_classB   };  
   
      void   setObj(classA*   p)  
      {  
            holder_   =   static_cast<void*>(p);  
            id_   =   ID_classA;  
        }  
      void   setObj(classB*   p);   //   the   same  
      void*   getObj()  
      {  
              return   holder_;  
        }  
      classA*   getObj(classA_tag)  
      {  
              return   id_   ==   ID_classA   ?   static_cast<classA*>(holder_)   :   0;  
        }  
      classB*   getObj(classB_tag);   //the   same  
      int   getObjType()   {   return   id_;   }  
   
  private:  
      void   *   holder_;  
      ID_T   id_;  
  };  
   
  这没办法在编译期就决断,为了减轻一点使用上的负担  
  只有这样  
  holder   hobj;  
  classA   *pobjA   =   new   classA();  
  hobj.setObj(pobjA);  
   
  //....  
   
  classA   *pa   =   0;  
  if   (   (pa   =   hobj.getObj(classA_tag()))   !=   0   )   {  
        pa->.....;  
  };  
   
  暂时只有这样了....  
   
  同样,如果要判断一个holder的类型  
   
  switch   (hobj.getObjType())  
  {  
        case   holder::classA_ID:  
              pa   =   hobj.getObj(classA_tag());  
              break;  
  //....  
  //或者自己来  
        case   holder::classB_ID:  
              pb   =   static_cast<classB*>(hobj.getObj());  
              break;  
  };  
  Top

8 楼dot99(又来混CSDN来了)回复于 2004-12-04 13:32:25 得分 0

imRainman   的办法不错~~~:D  
  或者,干脆点~~~  
  有轮子了~~我们使用  
  boost::anyTop

9 楼dot99(又来混CSDN来了)回复于 2004-12-04 13:35:16 得分 0

楼主~~~也可以把我那个东东用template扩展成rainman的那个样子~~~  
  嘿嘿~  
  自己来咯  
   
  不过,我还是推荐boost::any  
   
  Top

10 楼imRainman(雨人)回复于 2004-12-04 14:13:42 得分 0

呵呵,boost::any就不用啦,  
   
  我那个CAnyType就是个boost::any的盗版   :@)Top

11 楼vivalite_wei()回复于 2004-12-04 14:42:02 得分 0

谢谢两位高人了!!!!Top

相关问题

  • 简单但让我头痛的问题
  • 非常头痛的简单问题
  • 肯定很简单,但我却不知道的问题!头痛!!
  • 一个头痛的简单问题,惭愧啊。
  • TDateTimeEditEh自动调整的问题,头痛ing……
  • 简单问题,崩溃ing
  • 一个简单而又令我头痛的问题,高分相送。
  • 关于JAVA的CAST真是头痛,哪位有些简单的口诀没有?
  • 两个简单问题!但对我来说是非常头痛的问题!
  • 一些头痛问题,有简单的,有难的,大家出力帮解决!!!

关键词

  • 指针
  • canytype
  • pobject
  • getfiledirgroup
  • classa
  • hobj
  • 实例
  • holder
  • ctheobject
  • pointertype

得分解答快速导航

  • 帖主:vivalite_wei
  • dot99
  • imRainman

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo