可以有3种不同数据类型C++的向量

Jon*_*ney 12 c++ polymorphism vector

我正在尝试在C++中创建一个可以存储3种不同数据类型的向量.我不想使用boost库.就像是:

vector<type1, type2, type3> vectorName; 
Run Code Online (Sandbox Code Playgroud)

我需要制作模板吗?如果是,我该怎么做?

App*_*ish 13

在同一向量中存储多个类型的最简单方法是使它们成为父类的子类型,如果它们不是类,则将所需类型包装在类中.

std::vector<std::variant<type1, type2, type3>> vectorName; 
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建一个variant指针向量,可以存储指向子类型的指针:

class Parent
{
  //anything common to the types should be declared here, for instance:
  void print() //make this virtual if you want subclasses to override it
  {
     std::cout << "Printing!";
  }

  virtual ~Parent(); //virtual destructor to ensure our subclasses are correctly deallocated
};

class Type1 : public Parent
{
    void type1method();
};

class Type2 : public Parent
{
    void type2Method();
};


class Type3 : public Parent
{
    void type3Method();
};
Run Code Online (Sandbox Code Playgroud)

直接从向量访问元素时,您将只能使用属于的成员std::variant<type1, type2, typ3>.例如,你可以写:

std::vector<Parent*> vec;

vec.push_back(new Type1);
vec.push_back(new Type2);
vec.push_back(new Type3);
Run Code Online (Sandbox Code Playgroud)

但不是:

vec[0]->print();
Run Code Online (Sandbox Code Playgroud)

由于元素类型已声明为type1,且type2类型没有type3..

如果需要访问特定于子类型的成员,可以将std::vector指针转换为子类型指针,如下所示:

vec[0]->type1Method();
Run Code Online (Sandbox Code Playgroud)

虽然通常认为避免这种显式类型分支更好的想法,而是依赖虚拟方法.

如果使用动态分配,请确保在从向量中删除指针之前删除指针,就像我在上面的示例中所做的那样.或者,使用智能指针(可能std::variant)并让你的记忆自己照顾:

Parent *p = vec[0];

Type1 *t1 = nullptr;
Type2 *t2 = nullptr;
Type3 *t3 = nullptr;

if (t1 = dynamic_cast<Type1*>(p))
{
    t1->type1Method();
}
else if (t2 = dynamic_cast<Type2*>(p))
{
    t2->type2Method();
}
else if (t3 = dynamic_cast<Type3*>(p))
{
    t3->type3Method();
}
Run Code Online (Sandbox Code Playgroud)

  • 你没有删除任何东西。为什么不使用 unique_ptr 向量以便它自动删除它?父级需要一个虚拟析构函数。 (2认同)

Paw*_*arz 7

我正在尝试在C++中创建一个可以存储3种不同数据类型的向量.

这里的答案实际上取决于具体的用例:

  1. 如果对象以某种方式以某种方式连接和相似 - 创建一个基类并从中派生所有类,然后将向量存储unique_ptr设置为父类(有关详细信息,请参阅ApproachingDarknessFish的答案),

  2. 如果对象都是基本的(如此内置的)类型 - 使用union对类型进行分组并定义a vector<yourUnionType>,

  3. 如果对象属于未知类型,但您确定它们共享一个类似的接口,则创建一个基类,并从它(template <typename T> class container: public parent{};)派生一个模板化的子类,并vector<unique_ptr<parent>>在第一种情况下创建一个类似的,

  4. 如果对象是,由于某种原因不能被连接的类型(从而例如vector商店int,std::stringyourType),它们通过一个连接union在,例如2.或者 - 甚至更好......

...如果你有时间并且想要学习一些东西 - 看看如何boost::any实现并尝试自己实现它,如果你真的不想使用库本身.它并不像看起来那么难.