指向派生对象的指针的自动下转换
Automatic downcast of a pointer to a derived object
早上好,
我有一个模板化的类,我想通过指针向量来操作对象。要使用指向模板化类的指针向量,我需要从非模板化类派生这个类,我做到了
我的问题是:要从基类的指针调用派生类的方法,我不能使用虚拟函数,因为模板函数不能变成虚拟函数。我需要进行显式转换,这很乏味:一旦用new创建了一个数字对象,事实上,需要向下转换为数字*,尽管事先知道该对象是数字。
我用一种尴尬的方式解决了这个问题:函数myset测试typeid的所有支持值,以获得正确的动态类型转换。它是一长串执行typeid检查的嵌套if。
除了繁琐之外,该函数只适用于调用"set"方法,并且应该为调用其他方法定义类似的函数。如果我能对我所指向的对象进行自动铸造,这一切都会简单得多。
这种方法的缺点是:
- 代码是重复的:如果我定义了另一个函数(如Tget(){return val;},我将需要另一个myget函数和一整套嵌套的if
- 支持的类型列表必须通过嵌套if调用显式定义
- 代码可能效率低下
编译器知道lst[0](在下面的代码中)指向一个数字对象,尽管lst是元素对象的向量,其中数字<>对象是派生的。
有没有一种方法可以自动将定义为base*的指针向下转换为指向实际指向的对象的指针?
如果我有正确的下转换,那么我可以在数字<>中定义数千个方法类并用propercasting->函数调用它们(…)调用
以下是代码(它工作正常,核心是"myset"的定义)
提前感谢,Pietro M.
PS我最感兴趣的是标准C++方法,而不使用除STL之外的其他库,如Boost。
#include <iostream>
#include <vector>
#include <typeinfo>
using namespace std;
class element
{
public:
virtual void print() = 0; // print is not templatized and works properly
//template <class T> virtual set(T v) = 0; // this would solve all my problems, if only it were legal.
};
template <class T>
class number : public element
{
T val;
public:
void print() {cout << "number is " << val << endl;}
void set(T v) {val = v;}
};
// That's the best I can do!
template <class T>
void myset(T v, element *ptr)
{
// There is a kink in the template: the compiler checks the T type by the value of v, that in this case is an integer:
// cout << "Type name for the template is: " << typeid(T).name() << endl;
// cout << "Type name for an integer is: " << typeid(int).name() << endl;
if (typeid(*ptr) == typeid(number<double>))
{
((number<double> *) ptr) -> set(7);
return;
}
else if (typeid(*ptr) == typeid(number<float>))
{
((number<float> *) ptr) -> set(7);
return;
}
// add other types... (tedious)
else
{
cout << "type not supported" << endl;
}
}
int main()
{
vector <element *> lst; // list of heterogeneous templatized objects
lst.push_back(new number<float>);
lst.push_back(new number<double>);
lst[0] -> print();
//((number<float> *) lst[0]) -> set(7); it's correct but it requires I know the type when I call it (tedious)
myset(7, lst[0]); // may be inefficient, but it works (for the types which are explicitly supported)
// cast_to_what_the_pointer_actually_points_to <lst[0]> -> set(7); // that's what I'd like to do: a downcast function which checks the object type and returns the correct pointer would be able to call any class method...
lst[0] -> print();
}
您已接近目标。您需要有一个模板化的set
方法,该方法调用具有typeid
和指向其参数的void *
指针的私有虚拟方法,从而允许重写决定如何处理它:
class element
{
virtual void set_impl(const std::type_info &, const void *) = 0;
public:
template <class T> void set(T v) { set_impl(typeid(v), &v); }
};
并举例说明如何编写set_impl
:
template <class T>
class number : public element
{
T val;
void set_impl(const std::type_info &ti, const void *pv) {
if (ti == typeid(T)) {
val = *static_cast<const T *>(pv);
} else {
throw std::invalid_argument("incorrect type to set()");
}
}
};
这类似于Boost.Any.
相关文章:
- 转换指针引用的字符串
- 无法向上转换指针到指针参数
- 混合转换指针和引用
- 堆栈对象的强制转换指针
- 基类到派生模板类的强制转换指针,而不知道类型
- 删除类型转换指针的最佳方法
- 管理到本机值类转换:强制转换指针是否安全?
- 转换指针类型
- 为什么函数不能正确强制转换指针(从基类到派生类)
- 当我们递增下面的类型转换指针时会发生什么?
- 类型强制转换指针构造函数调用
- 如何转换(指针向量)-->(指向指针数组的指针)
- 如何从类功能转换指针
- 在C++对象中:我应该使用父类强制转换指针,还是应该使用实际类本身进行强制转换
- Delphi中的类型转换指针添加
- C++分段错误(核心转储)错误 - 强制转换指针/将函数值返回到线程
- 以C++和运算符优先级键入指向数组成员的强制转换指针
- C++动态强制转换指针的内存清理
- 转换指针和引用的好处
- 在c++中转换指针