写一个C++泛型集合,几个问题无法解决,希望专家指点一下,谢谢。

roki_chen 2010-12-07 10:12:38
举例 我想自己实现一个C++泛型集合

遇到了2个问题,
1.值类型和引用类型转换
我考虑使用一个 值类型模板,一个引用类型模板
下面是值类型模板代码

2.如何让不同类型的模板对象,用相同的父类指针引用。
例如 :
ValueList<int> *m_intList = new ValueList<int>();
ValueList<double> *m_doubleList = new ValueList<double>();

能否统一类型调用呢?
例如
IList *m_list = new ValueList<int>();
IList *m_list = new ValueList<double>();
类似这种写法 ?


#include "valuetypenullflag.h"
#include "ilist.h"
#pragma once

namespace Generic
{
template<class T> class ValueList : public IList
{
private:
T *m_array;
int m_count;
int m_arrayLength;
int m_index;
T m_flag;
public:

ValueList(T flag)
{
this->m_array = new T[4];
this->m_arrayLength = 4;
this->m_index = -1;
this->m_flag = flag;
for (int i = 0 ;i < 4; i++)
{
this->m_array[i] = this->m_flag ;
}
}

~ValueList(void)
{
}

public:
int Count() const
{
for(int i = 0 ; i < this->m_arrayLength ; i ++)
{
if(this->m_array[i] == this->m_flag)
{
return i ;
}
}
return this->m_arrayLength;
}
int ArrayLength() const { return m_arrayLength; }
public:
int Add(T item)
{
bool canAdd = false;
for (int i = 0;i< this->m_arrayLength;i++)
{
if(this->m_array[i] == this->m_flag)
{
canAdd = true;
this->m_array[i] = item;
return i;
}
}

if(!canAdd)
{
int i = this->ExtendArray();
this->m_array[i] = item;
return i;
}
return -1;
}

T GetItem(int index)
{
return this->m_array[index];
}
private:
int ExtendArray()
{
int originalArrayLength = this->m_arrayLength;
T *cloneArray = this->m_array;
this->m_array = new T[this->m_arrayLength * 2];
//memset(this->m_array,0,sizeof(int) * this->m_arrayLength * 2);

for(int i = 0 ; i < this->m_arrayLength * 2 ; i++)
{
this->m_array[i] = this->m_flag;
}

this->m_count = this->m_arrayLength;

for (int i = 0; i < this->m_arrayLength; i++)
{
this->m_array[i] = cloneArray[i];
}

this->m_arrayLength *= 2;

return originalArrayLength;
}
};
}


谢谢大家帮我解答 :)
...全文
135 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
canf07 2012-09-08
  • 打赏
  • 举报
回复
c++的模板工作方式类似动态预处理,应该是不能编译成dll的
ssdx 2010-12-08
  • 打赏
  • 举报
回复
dll恐怕不行
ryfdizuo 2010-12-08
  • 打赏
  • 举报
回复
_declspec(dllexport) class List

你是要导出dll啊?
  • 打赏
  • 举报
回复
模板强调类型
多态不强调类型
不容易混杂到一起
bluewanderer 2010-12-07
  • 打赏
  • 举报
回复
虚函数不就好了...?
失落的凡凡 2010-12-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 milkylove 的回复:]

可以,但接口受到很大限制。虚函数要求接口返回值必须一致,像int Count()是可以的, int Add(T item)就不可以。
[/Quote]

啊 口误 我的意思是 接口的原型必须一致
ryfdizuo 2010-12-07
  • 打赏
  • 举报
回复
能否统一类型调用呢?  
例如
IList *m_list = new ValueList<int>();
IList *m_list = new ValueList<double>();
类似这种写法 ?

---------------------
IList只是声明抽象接口,将模板子类转化为一般父类,会丢失类型信息,提供一种思路供参考:


class IList
{
public:
template<class T>
int Add(T item)
{
ValueList<T>* vlist = dynamic_cast<ValueList<T>*>(this);

if (!vlist)
return false;

return vlist->Add(item);
}

template<class T>
T GetItem(int index)
{
ValueList<T>* vlist = dynamic_cast<ValueList<T>*>(this);

if (!vlist)
return false;

return vlist->GetItem(item);
}
};

template<class Type>
class ValueList : IList
{
public:
};
失落的凡凡 2010-12-07
  • 打赏
  • 举报
回复
可以,但接口受到很大限制。虚函数要求接口返回值必须一致,像int Count()是可以的, int Add(T item)就不可以。
roki_chen 2010-12-07
  • 打赏
  • 举报
回复
因为如果不能抽象类型,要写很多的switch不方便扩展...
roki_chen 2010-12-07
  • 打赏
  • 举报
回复
错误 3 error C2783: “T IList::GetItem(int)”: 无法为“T”推导 模板 参数 d:\c++\cppcollections\cppcollections\list.h 57 TestCppCollections

错误是因为如下代码,无法确定类型
但是IList不是多态类 还是没发现怎么回事

template<class T>
T GetItem(int index)
{
ValueList<T> *vlist = dynamic_cast<ValueList<T>*>(this);
if(!vlist) {return false;}
return vlist->GetItem(index);
}
roki_chen 2010-12-07
  • 打赏
  • 举报
回复
我用了这种方式报错
错误 3 error C2683: “dynamic_cast”:“IList”不是多态类型 d:\c++\cppcollections\cppcollections\ilist.h 9 TestCppCollections

错误 3 error C2783: “T IList::GetItem(int)”: 无法为“T”推导 模板 参数 d:\c++\cppcollections\cppcollections\list.h 57 TestCppCollections

我的调用代码
#include "valuelist.h"
#include <string>
#pragma once

using namespace Generic;
using namespace std;
enum ArrayTypes
{
Int = 0,
Double = 1,
};
_declspec(dllexport) class List
{
private:
IList *m_intList;
IList *m_doubleList;

public:

List(ArrayTypes type)
{
int typeId = (int)type;

switch(typeId)
{
case 0:
m_intList = new ValueList<int>(-2147483648);
break;
case 1:
m_doubleList = new ValueList<double>(2.22507e-308);
break;
default:
break;
}
}

~List(void)
{
delete []this->m_intList;
delete []this->m_doubleList;
}

int Add(int item)
{
int index = m_intList->Add(item);
return index;
}
int Add(double item)
{

int index = m_doubleList->Add(item);
return index;
}

int GetItem(int index)
{
return this->m_intList->GetItem(index);
}
};


[Quote=引用 2 楼 milkylove 的回复:]
可以,但接口受到很大限制。虚函数要求接口返回值必须一致,像int Count()是可以的, int Add(T item)就不可以。
[/Quote]

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧