【问题标题】:storing two different class objects in a vector在向量中存储两个不同的类对象
【发布时间】:2015-07-13 04:51:23
【问题描述】:

我试图找到一种在一个向量中存储两个不同类对象的好方法,每个对象在向量中都有自己的位置,因此可以在以后需要时存储和访问这些对象。

我使用了一个结构,但是我将结构所具有的所有内容都存储到了我不想要的向量中,我将举例说明我的意思。

Class A{
   public:
     void changeNumber(int x) {number = x;}
   private:
     int number;
};

Class B{
   public:
     void changeNumber(int x) {number = x;}
   private:
     int number;
};

struct Object{
   A a;
   B b;
};

Class Main{
   public:
     void storeObject(Object ob) {object.push_back(ob);}
   private:
     std::vector<Object> objects; //when an object is passed both A and B objects are stored within the vector in the same location
};

有没有一种方法可以在一个对象中存储两个不同的类对象,但一次只传递一个来存储,所以我在向量中有自己的索引?

【问题讨论】:

  • 你到底想用这个实现什么?您可能想要的是一个公共基类class A : Base {...,然后将指向Base 的指针存储在std::vector&lt;Base*&gt; objects 中,但我可能会误解struct Object 背后的意图。
  • 我正在尝试存储两个不同的类对象,它们将具有不同的函数和不同的变量,但我想将这两个类对象存储在一个向量中,这样我可以更轻松地循环大小向量并完成需要完成的任务。 @mbschenkel

标签: c++ class vector


【解决方案1】:

如果AB 有共同的函数,而您只在向量的元素上调用这些函数,您可以使用所有共同的成员和成员函数并从中创建一个基类。然后使AB 派生类Object

class Object
{
public:
    virtual ~Object() = default;

    void changeNumber(int x) { number = x; }

private:
    int number;
};

class A : public Object
{
    // extension of Object
};

class B : public Object
{
    // extension of Object
};

在这种情况下,AB 没有区别,所以一切都在Object 中实现。

最后,您的矢量将如下所示:

std::vector<Object*> objects;

这里是std::shared_ptr 的更优选解决方案,它在元素从向量中删除或以其他方式破坏后为您释放内存。

std::vector<std::shared_ptr<Object>> objects;

存储对象:

void storeObject(std::shared_ptr<Object> const& ob)
{
    objects.push_back(ob);
}

// Example calls
Main main;
main.storeObject(std::make_shared<Object>(A())); // store A
main.storeObject(new A()); // logically same as above

main.storeObject(std::make_shared<Object>(B())); // store B
main.storeObject(new B());

boost::variant 是存储多个不能使用继承的不同类型时要走的路。

【讨论】:

  • 感谢您的回复,所以如果 A 类和 B 类继承自 Object 类,但它们也有自己独立的功能,我会说不能将它们都存储在一个向量中是正确的不使用boost::variant? @LogicStuff
  • @Jack 我不知道除了答案中提到的任何其他方式。如果你想打电话给objects[index]-&gt;functionOfA()objects[index]-&gt;functionOfB(),那就不要了。但是不要忘记可以使一些虚函数被覆盖。它甚至可以通过继承实现,您可能不知道。
  • @LogicStuff std::any 怎么样?
【解决方案2】:

您可以使用boost::variant。它是可以表示一组有限类型的类型,在您的示例中,您将拥有一个

std::vector<boost::variant<A,B> > objects;

另一种选择(它并不真正适合您的用例,但可能适合未来的读者)是boost::any。如果您在编译时没有可能类型的有限列表,它可以表示任何有用的类型。

【讨论】:

    【解决方案3】:

    如果您更喜欢使用自己的“variant 等效项”。您可以按照以下方式做一些事情

    struct Object{ 
        std::shared_ptr<A> a; 
        std::shared_ptr<B> b;
    };
    
    std::vector<Object> objects;
    
    Object one; 
    one.a = std::make_shared<A>();
    objects.push_back(one);
    
    Object two; 
    two.b = std::make_shared<B>();
    objects.push_back(two);
    
    for(auto object: objects) {
         if(object.a) {
              object.a->changeNumber(1);
         } else if(object.b) {
              object.b->changeNumber(2);
         }
    }
    

    但是,我仍然认为使用适当的继承方案(如the other answer)解决这个问题要干净得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 2013-06-20
      • 2011-09-10
      相关资源
      最近更新 更多