模板对象数组
Array of template objects
我不知道如何解决模板和继承的问题。
在我的代码中有一个模板化类,它看起来或多或少像:
template<typename T>
class Derived : public Base{
T value;
public:
Derived(T arg) { value=arg; };
T getValue() { return value;};
};
class Base{
};
基类的唯一目的是对派生类的对象数组进行分组。形参T通常是双精度、浮点数或复数,尽管int和struct也可能有用。(以后应该会有几个类似的派生类,带有一些额外的函数。)
我可以创建这样一个组
Base** M = new Base*[numElements];
,并将派生类的元素赋值给它们,例如:
M[54] = new Derived<double>(100.);
但是我怎样才能知道第55个元素的值是100呢?我需要像
这样的东西virtual T getValue() = 0;
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); }
};
现在你可以为你想在集合上做的每个操作定义访问者,例如,将每个元素转换为字符串,每种类型都有不同的格式,或者将每个元素存储到一个文件中,其中每种类型可以占用不同数量的空间。
您可以将重载的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;
}
};
例如:
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;
}
注意,你不能用一个模板化的方法替换基类中的has_value方法,因为虚方法不能被模板化。
在基类中添加一个方法"getDouble"。派生类必须实现此方法,并根据需要将自己的类型强制转换为double类型。
NO。由于两个原因,实际上不可能有这样的功能:
-
Base
不能作为模板,如你需要一个通用句柄来存储数组,可以包含任何类型的Derived
like<int>, <double>, <float>, any struct <abc>
. - 你不能在
Base
里面有template virtual
方法,因为语言不允许
解决这个问题的简单方法是为每个类型都有"getter"方法,如get_double()
, get_int()
, get_float()
, get_abc()
等。但是,您的Base
将会被这些方法弄得乱七八糟。
您可以使用dynamic_cast来知道它是什么类型(除了@StackedCrooked所说的内容之外)。这将需要在基类中定义一些虚函数,但在那里已经需要一个虚析构函数(以便能够通过基类指针删除值)。
作为一种替代方法,您可以尝试boost::variant或boost::any:)
使用boost::any将对象存储在数组中。然后,当您想对其进行操作时,您可以使用boost::any_cast对您可能拥有的类型进行操作。
- 销毁C++中动态分配的内存(数组对象)
- 数组对象的生存期是否在重用其元素存储时结束?
- 为什么顶点数组对象会导致错误?
- 具有纯虚函数和指针数组对象类型的父类的指针数组
- 这是使用构造函数初始化数组对象的最佳方法吗?
- OpenGL 顶点数组对象与 tinyobjloader
- 将数组/对象/结构列表从C#库中传递给C MFC应用程序
- C++ RapidJson 帮助反序列化数组对象
- ptrdiff_t可以表示指向同一数组对象元素的指针的所有减法吗?
- 检查成员函数是否返回临时对象或数组对象
- 为什么 std::variant 不能容纳数组对象类型,而联合可以?
- 当数组对象以函数参数传递时,为什么复制构造函数会自称
- 如何使用箭头指针打印出一类数组对象,这些对象中有多个分数
- C++17 std::shared_ptr<> 类数组对象的重载运算符 []
- 添加两个具有运算符重载的数组对象,从而导致分段错误
- opengl:两个不同的矢量可以绑定到同一个顶点数组对象吗
- 使用相同的数据填充数组对象或使用指针
- 方法用于最快的分配,并且不需要将动态大小的数组对象作为局部变量
- 如何将2d数组对象传递给c++中的函数
- ReferenceTable溢出(jni-android),数组对象释放