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

怎么将携带模板的基类指向派生类,然后进行统一的操作呢

2012-04-01 
如何将携带模板的基类指向派生类,然后进行统一的操作呢我们知道可以将基类指针指向不同的派生类,通过调用

如何将携带模板的基类指向派生类,然后进行统一的操作呢
我们知道可以将基类指针指向不同的派生类,通过调用基类中的虚函数来实现代码架构的统一和简化。
可是如果基类中带有模板的话,应该怎样写才对呀,请不吝赐教!

//携带模板的基类定义
template <class TYPE>
class CBase
{
public:
  virtual TYPE *Find(int lKey)
  {
  map<int, TYPE>::iterator iter;

  iter = m_Map.find(lKey);
  if (iter == m_Map.end())
  {
  printf("Not find\n");
  return NULL;
  }
  else
  {
  cout << "Find it. val = " << iter->second << endl;
  return &iter->second;
  }
  }
  virtual TYPE *Insert(int lKey, TYPE val)
  {
  pair<map<int, TYPE>::iterator, bool> pr;

  pr = m_Map.insert(pair<int, TYPE>(lKey, val));
  if (!pr.second)
  {
  printf("Insert fail\n");
  return NULL;
  }

  return &pr.first->second;
  }
  virtual void Delete(int lKey)
  {
  m_Map.erase(lKey);
  }

public:
  map<int, TYPE> m_Map;
};

//派生类1
class CDerive1: public CBase<int>
{
};

//派生类2
class CDerive2: public CBase<float>
{
};

//通过此类中的FindTbl获取指向不同派生类的基类指针,然后调用其虚函数进行操作
class CProc
{
public:
  CBase *FindTbl(int lIndex)
  {
  if (1 == lIndex)
  {
  return &m_Tbl1; //这里编译不过
  }
  else if (2 == lIndex)
  {
  return &m_Tbl2;
  }
  else
  {
  return NULL;
  }
  }
public:

  CDerive1 m_Tbl1;
  CDerive2 m_Tbl2;
};


编译错误为:error C2440: 'return' : cannot convert from 'class CDerive1 *' to 'class CBase *'

[解决办法]
所以这里也不构成lz认为的同一个基类,不同的派生类:

class CDerive1: public CBase<int>
{
};

//派生类2
class CDerive2: public CBase<float>
{
};

CDerive1和CDerive2的基类是两个类,而不是一个类!
[解决办法]
下面的代码,供楼主参考:

C/C++ code
#include <iostream>using namespace std;template<typename T>class Base{private:    T base_t;public:    Base(T t)    {        base_t = t;    }    virtual void printInfo()    {        cout << base_t << endl;    }};template<typename T>class Derived1 : public Base<T>{private:    T derived1_t;public:    Derived1(T t):Base(t + 1)    {        derived1_t = t;    }    //可以去掉下面的注释试试    //void printInfo()    //{    //    cout << derived1_t << endl;    //}};template<typename T>class Derived2 : public Base<T>{private:    T derived2_t;public:    Derived2(T t):Base(t + 2)    {        derived2_t = t;    }    //可以去掉下面的注释试试    //void printInfo()    //{    //    cout << derived1_t << endl;    //}};int main(int argc, char** argv){    Base<int>* pb = new Base<int>(1);    pb->printInfo();    pb = new Derived1<int>(1);    pb->printInfo();    pb = new Derived2<int>(1);    pb->printInfo();    delete pb;    return 0;}
[解决办法]
C/C++ code
#include <iostream>using namespace std;template <class T>class A{public:        A(){}        virtual void func(){}        virtual ~A(){}};class B:public A<int>{public:        B(){}        virtual void func(){}        virtual ~B(){}};class C:public A<float>{public:        C(){}        virtual void func(){}        virtual ~C(){};};class D{public:        template <class T>        bool getObj(int index,A<T>* *ret)        {                if(index==1)                {                        *ret=static_cast< A<int>* >(&b);                        return true;                }                else if(index==2)                {                        *ret=static_cast< A<float>* >(&c);                        return true;                }                return false;        }private:        B b;        C c;};int main(){        D d;        A<int> *pB;        A<float> *pC;        if(d.getObj(1,&pB))        {                pB->func();        }        if(d.getObj(2,&pC))        {                pC->func();        }        if(!d.getObj(3,&pB))    //运行报错        {                cout<<"index 3 not exists"<<endl;        }/*        A<double> *pNotExist;        if(d.getObj(1,&pNotExist))      //编译报错        {        }*/        return 0;} 


[解决办法]

探讨

有一点儿要声明一下,之所以想这样写,就是因为各个派生类很多实现类似,但数据定义不同。按理说模板就是搞这个的,的确在基类中的实现可以说已经已经封装了各个派生类的实现,达到了简化代码的目的。

但是在main函数中,我要处理所有的派生类,而且处理的逻辑也相同,所以就想在main函数中使用一个统一的指针指向不同派生类(不能在main中再出现派生类相关定义),使处理逻辑的代码也能够简化。

不管……

[解决办法]
情况就像9楼说的一样。
按照你18楼所描述的需要,最好用接口。
这个你权当参考下吧:

#include <iostream>
#include <stdlib.h>
#include<vector>
#include <windows.h>
#include <string>
#include <stdio.h>
#include <map>
using namespace std;

class Interface
{
public:
virtual show()=0;
};

template <class TYPE>
class CBase:public Interface
{
public:
virtual TYPE *Find(int lKey)
{
map<int, TYPE>::iterator iter;

iter = m_Map.find(lKey);
if (iter == m_Map.end())
{
printf("Not find\n");
return NULL;
}
else
{
cout << "Find it. val = " << iter->second << endl;
return &iter->second;
}
}
virtual TYPE *Insert(int lKey, TYPE val)
{
pair<map<int, TYPE>::iterator, bool> pr;

pr = m_Map.insert(pair<int, TYPE>(lKey, val));
if (!pr.second)
{
printf("Insert fail\n");
return NULL;
}

return &pr.first->second;
}
virtual void Delete(int lKey)
{
m_Map.erase(lKey);
}
virtual show(){}
virtual ~CBase(){}
public:
map<int, TYPE> m_Map;
};
//派生类1
class CDerive1: public CBase<int>
{
public:
virtual show(){
cout<<"CDerive1"<<endl;
}
~CDerive1(){}
};

//派生类2
class CDerive2: public CBase<float>
{
public:
virtual show(){
cout<<"CDerive2"<<endl;
}
~CDerive2(){}
};

//通过此类中的FindTbl获取指向不同派生类的基类指针,然后调用其虚函数进行操作
class CProc
{
public:
Interface *FindTbl(int lIndex)
{
if (1 == lIndex)
{
return &m_Tbl1; //这里编译不过
}
else if (2 == lIndex)
{
return &m_Tbl2;
}
else
{
return NULL;
}
}
public:

CDerive1 m_Tbl1;
CDerive2 m_Tbl2;
};

int main()
{
Interface* itf;
CProc c;
itf = c.FindTbl(2);
itf->show();
itf = c.FindTbl(1);
itf->show();
return 0;
}
[解决办法]
探讨

TNND,linux下怎么连如下定义都不认,不加模板到可以识别

map<int, T>::iterator iter;

test.cpp:11: error: type ‘std::map<int, T, std::less<int>, std::allocator<std::pair<const int, T> > >’ is not derived from type ‘CBas……

热点排行