我不知道如何解决模板和继承问题。
在我的代码中有一个模板化的类看起来或多或少像:
template<typename T>
class Derived : public Base{
T value;
public:
Derived(T arg) { value=arg; };
T getValue() { return value;};
};
class Base{
};
我的Base类的唯一目的是对Derived类的对象数组进行分组。参数T通常是double,float或complex,尽管int和structs也可能变得有用。 (稍后应该有几个类似的派生类和一些附加功能。)
我可以创建这样一个组
Base** M = new Base*[numElements];
并将派生类的元素分配给它们,例如:
M[54] = new Derived<double>(100.);
但是我怎么能发现第55个元素后来有价值100? 我需要像
这样的东西virtual T getValue() = 0;
但是T是派生类的类型名称,对于此数组的任何两个元素可能不同。
答案 0 :(得分:4)
Visitor
模式可能是您最好的选择。迭代数组的代码必须提供一个“访问者”对象,该对象知道如何处理各种类型。
struct NumericVisitor
{
virtual void visit(double) = 0;
virtual void visit(int) = 0;
virtual void visit(unsigned char) = 0;
};
struct Visitable
{
virtual void visitValue(NumericVisitor& visitor) = 0;
};
template<typename T>
class Derived : public Visitable
{
T value;
public:
Derived(const T& arg) value(arg) {}
void visitValue(NumericVisitor& visitor) { visitor.visit(value); }
};
现在,您可以为要对集合执行的每项操作定义访问者,例如将每个元素转换为字符串,每种类型具有不同的格式,或将每个元素存储到文件中,其中每种类型可占用不同的空间量。
答案 1 :(得分:2)
您可以将重载的has_value()
方法添加到Base
类:
class Base
{
public:
virtual ~Base () {}
virtual bool has_value (int i) {return false;}
virtual bool has_value (double d) {return false;}
virtual bool has_value (const std::string& s) {return false;}
// etc.
};
您在Derived
班级中覆盖的其中一个:
template<typename T>
class Derived : public Base
{
T value;
public:
Derived(T arg) {value=arg;}
T getValue() { return value;}
virtual bool has_value (T t)
{
return t == value;
}
};
E.g:
bool test ()
{
std::vector<Base*> bases;
bases.push_back (new Derived<double> (1.234));
bases.push_back (new Derived<int> (100));
bases.push_back (new Derived<std::string> ("zap"));
for(std::vector<Base*>::const_iterator iter = bases.begin (); iter != bases.end (); ++iter)
if ((*iter)->has_value (100))
return true;
return false;
}
注意,您不能使用单个模板化方法替换Base类中的has_value方法,因为无法模拟虚拟方法。
答案 2 :(得分:0)
将方法“getDouble”添加到基类。然后派生类必须实现此方法,并在需要时将它们自己的类型转换为double。
答案 3 :(得分:0)
您可以使用dynamic_cast来了解它的类型(除了@StackedCrooked所说的内容)。 它需要在基类中定义一些虚函数,但是你已经需要一个虚拟析构函数(能够通过基类指针删除值)。
作为替代方案,您可以尝试使用boost :: variant或boost :: any:)
答案 4 :(得分:0)
NO。由于两个原因,实际上不可能有这样的功能:
Base
不能像你一样成为模板
想要一个通用句柄来存储
数组,可以包含任何类型的
Derived
,如<int>, <double>, <float>,
any struct <abc>
。template
virtual
内无法使用Base
方法,
因为语言不允许它解决此问题的简单方法是为get_double()
,get_int()
,get_float()
,get_abc()
等所有类型设置“getter”方法。但是,您的Base
将会混淆这些方法。
答案 5 :(得分:0)
使用boost :: any将对象存储在数组中。然后,当你想对它进行操作时,可以将boost :: any_cast用于你可能的类型。