本帖最后由 Croper 于 2020-1-6 21:31 编辑
本来以为很简单一个问题。。突然发现我纠结到了。
比如说这里有一个模板类A:template <typename T>
class A{
public:
//....其他数据成员
T data; //某个数据成员
//..其他成员函数
};
为了方便访问它,写了一个接口类,并让模板类继承://接口类
struct IA {
//virtual IA* copy() =0;
//virtual int id() =0;
//...其他接口..blalblabla..
};
//模板类
template <typename T>
class A :public IA {
public:
//....其他数据成员
T data; //某个数据成员
//..其他成员函数
};
这个时候,我想通过IA来访问类A中的数据成员data。
类A是模板类,那么这个接口只能写成模板函数。。。
但是模板函数是不能写成虚函数的,想来想去,只想出两种方法:
//接口类
struct IA {
private:
virtual void* _GetData() = 0; //返回类型改为void*,这样能写成虚函数
public:
template <typename T> //然后再包装一下
T GetData() {
return *static_cast<T*>(_GetData());
}
};
//模板类
template <typename T>
class A :public IA {
public:
T data; //需要的数据成员
void* _GetData() override { //这是继承的函数
return &data;
}
};
这样写的问题是,即使模板函数GetData的类型和模板类不一致且无法转化,也不会报错,
而且类型之间的互相转化也是直接二进制数据强制转化,这肯定不是所期望的
//接口类
struct IA {
public:
template <typename T>
T GetData();
};
//模板类
template <typename T>
class A :public IA {
public:
T data; //需要的数据成员
};
template<typename T>
T IA::GetData()
{
return dynamic_cast<A<T>*>(this)->data; //将this指针转化为A<T>的指针
};
这样首先是不符合设计模式了,抽象类(底层)依赖具体实现(高层)。
另外,同样无法做到double与int的相互转化。
所以还有什么好点的写法么。。?
我仔细想了想,这个问题应该无解,至少我无解
这个问题要求C++能够记住类型信息,也就是要求C++能够正确读取 void *
试想一下,在new一个对象的时候保存这个对象的类型,然后把new出来的对象给void 指针保存,在使用的时候用之前保存的类型信息对void指针解引用
但是C++好像不能读取void *,我百度不到如何保存类型信息
|