# re: Void and void pointer
@zml_cnnk
不知道你具体代码是怎样的。
我猜可能是这样。 一个调用链上
1. 一开始是有类型的
2. 到了某个地方,使用了void*去保存任意类型,原来的类型就丢失了。
3. 需要析构,找不到类型了。
要想办法把类型信息带着。
举个标准库中的例子, 保存指针的容器:
vector vi;
vector vc;
vi.push_back( new int );
vc.push_back( new char );
实际上,不需要生成T=int*, T=char*这2套模板的代码。
void* 就可以保存任意对象的指针。
vector vi;
vector vc;
vi.push_back( new int);
vc.push_back( new char );
但这样就丢失了原来的类型。
取出时,就无法得知正确类型了。
delete vi[0]; // error, delete void*
delete vc[0]; // error, delete void*
所以,这里可以作一个偏特化。
template // 对指针类型做偏特化
class vector
{
vector c_; // 底层容器
public:
// 转发给底层容器
push_back(T* p)
{
// 隐式类型转换,void* 可以保存任意对象指针。
return c_.push_back(p);
}
// 取出
T* operator[](size_type index)
{
void* pv = c_[index]; // c_没有类型信息
T* p = staic_cast(pv); // 但这个偏特化模板含有类型信息,还原它
return p; // 返回带有类型信息的指针。
}
...
};
现在客户代码依然这么写:
vector vi; // 底层使用vector
vector vc;
vi.push_back( new int ); // 转发函数仅含有一个隐式转换,不生成代码
vc.push_back( new char ); // inline展开,直接调用vector::push_backinline
delete vi[0]; // 调用vector::operator [](index);
delete vc[0]; // 但类型信息没有丢失
OwnWaterloo 评论于 2009-11-25 01:11 回复 更多评论