在数组中保留模板类对象

Holding Template Class Objects in Array

本文关键字:对象 保留 数组      更新时间:2023-10-16

我必须在一个数组中为我的项目保存不同类型的数据。我创建了一个用于生成对象的模板类。

template<class Queue>
class Template  {
public:
    Queue value;
    Template(Queue input) {
        value = input;
    }
};

但如果不使用抽象类,我就无法将它们保存在一个数组中。我已经为此创建了一个空指针数组。我喜欢用它;

void *array[21];
array[index] = new Template<int>(number);
array[index] = new Template<string>(text);

没有抽象类,有什么可能的解决方案吗?我的意思是,我可以在模板类数组中保存这个模板对象吗?

创建层次结构并利用动态绑定:

class Base  {
public:
  virtual ~Base() {};
  // ...
};
template<class Queue>
class Template : public Base {
    Queue value;
public:
    Template(Queue const &input) :value(input) {}
    // ...
};

并将其用作:

Base *array[21];
array[index] = new Template<int>(number);
array[index + 1] = new Template<string>(text);

此外,不使用原始数组和原始指针,而是使用STL设施,如std::array智能指针(例如,std::shared_ptr<Base>std::unique_ptr<Base>):

std::array<std::unique_ptr<Base>, 21> arr;
arr[index].reset(new Template<int>(number));
arr[index + 1].reset(new Template<string>(text));

也更喜欢将成员变量初始化到构造函数的初始值设定项列表,而不是其主体。

这通常是一个迹象,表明您应该在更高的级别重新思考代码结构,这样您就根本不需要它了。

否则,我看到你有四个选择(如果你算上上面的"不要这样做",就有五个):

  1. 使用可以容纳所有类型数据的统一类型(例如std::string,并在需要时解析数字信息)。该功能可以封装在一个类中,该类提供成员函数以使其更容易实现。

  2. 使用boost::variant,如果你是C++的新手,那么我不建议你马上处理这类事情。

  3. 使用101010中解释的基类。我想补充一点,你可能需要在基类中有一个enum,它告诉你存储了什么类型的数据

  4. 使用boost::any,这比变体更难使用,尽管它更容易理解。

如果没有更多关于你想要实现的目标的信息,我们就无法为如何继续提供更好的指导。

我会使用变体类型来完成。您可以推出自己的产品,但更喜欢使用boost::variant:

#include <boost/variant.hpp>
#include <iostream>
#include <string>
using namespace std;
template<class Queue>
class Template  
{
public:
    Queue value;
    Template() = default; 
    Template(Queue input) {
        value = input;
    }
};
template<typename T>
std::ostream& operator<<(std::ostream& os, Template<T> const& t)
{
    os << t.value; 
    return os; 
}
int main ()
{
    using v_t = boost::variant<Template<int>, Template<string>>; 
    v_t ar[2]; 
    ar[0] = Template<int>(1); 
    ar[1] = Template<string>("lmfao"); 
    for (auto&& elem : ar) cout << elem << endl;
}

演示

注意

  • v_t是变体的类型
  • v_t可以有更多类型,您可以从中选择填充数组
  • 输出运算符只是为了演示而过载
  • 您可以通过boost::visitor获得额外功能