简体   繁体   English

C ++ - 将对象添加到std :: vector,在循环中实例化

[英]C++ - Adding objects to an std::vector, instantiated in a loop

I'm an expert level Java programmer, trying to port my knowledge over to C++. 我是一名专家级Java程序员,试图将我的知识转移到C ++。 This is not homework, just a concept that I'm trying to learn the C++ equivalent of. 这不是家庭作业,只是一个我试图学习C ++等同的概念。

What I'm trying to do, is "generate" a list of objects of a custom type using a loop. 我正在尝试做的是使用循环“生成”自定义类型的对象列表。 This is how I would do it in Java: 这是我在Java中的方式:

public class TestClass
{
   private ArrayList<ExampleClass> _exampleObjects;
   private int _numObjects = 10;

   public void populateList()
   {
      _exampleObjects = new ArrayList<ExampleClass>();

      for(int i = 0; i < _numObjects; i++)
      {
         _exampleObjects.add(new ExampleClass());
      }
   }

   public void doStuffWithListItems()
   {
      for(ExampleClass e : _exampleObjects)
      {
         e.performAction();
      }
   }
}

Super simple stuff. 超级简单的东西。 Create a list, iterate through an arbitrary loop and add objects to it. 创建一个列表,遍历任意循环并向其添加对象。 Then, loop through those objects and use them for whatever purpose. 然后,遍历这些对象并将它们用于任何目的。

TestClass.h: TestClass.h:

class TestClass
{
   public:
      // Constructor, copy constructor, destructor definitions

      void populateList();
      void doStuffWithListItems(); 
   private:
      std::vector<ExampleClass> _exampleObjects;
      const int _numObjects = 10;
};

TestClass.cpp: TestClass.cpp:

void TestClass::populateList()
{
   for(int i = 0; i < _numObjects; i++)
   {
      ExampleObject obj;
      _exampleObjects.push_back(obj); 

      /* What actually goes here in place of obj? */
   }
}

void TestClass::doStuffWithListItems()
{
   for(auto it = _exampleObjects.begin(); it != _exampleObjects.end(); it++)
   {
      /* What do i do with my iterator to access my object? */
   }
}

Its my understanding that where I initialise my objects in the first loop, they go out of scope and die by the end of each loop iteration. 我的理解是,在第一个循环中初始化我的对象时,它们会超出范围并在每次循环迭代结束时死亡。 Is that right? 是对的吗? If so, how do I make a persistent instance? 如果是这样,我如何创建持久化实例?

I experimented with the shared_ptr<> from and was apparently able to store them persistently, but couldn't for the life of me work out how to dereference from an iterator of a shared_ptr<>. 我尝试使用shared_ptr <>并且显然能够持久地存储它们,但是在我的生活中无法解决如何从shared_ptr <>的迭代器中取消引用。

I feel like this should be a really simple concept. 我觉得这应该是一个非常简单的概念。 I just can't seem to work it out. 我似乎无法解决这个问题。 I've read a lot on C++ scope and loops. 我已经阅读了很多关于C ++范围和循环的内容。 I just can't seem to find anything on both. 我似乎无法在两者身上找到任何东西。

ExampleObject obj;
_exampleObjects.push_back(obj); 

/* What actually goes here in place of obj? */

Nothing. 没有。 What you have is correct, assuming ExampleClass has a working copy constructor. 假设ExampleClass有一个工作副本构造函数,那么你所拥有的是正确的。 If your compiler supports C++11 (and since you're using auto , it at least partially does), you can save yourself a copy. 如果您的编译器支持C ++ 11(并且因为您使用的是auto ,至少部分使用auto ),您可以保存自己的副本。

_exampleObjects.emplace_back();

This constructs an object in place in the vector, forwarding the arguments (none in this case) to a matching constructor (the default ctor, in this case). 这会在向量中构造一个对象,将参数(在本例中为none)转发给匹配的构造函数(在本例中为默认的ctor)。 For accessing the object from the iterator, do this: 要从迭代器访问对象,请执行以下操作:

for(auto it = _exampleObjects.begin(); it != _exampleObjects.end(); it++)
{
   it->performAction();
}

Again, C++11 can make things better here. 同样,C ++ 11可以在这里做得更好。

for(auto & obj : _exampleObjects)
{
    obj.performAction();
}

Its my understanding that where I initialise my objects in the first loop, they go out of scope and die by the end of each loop iteration. 我的理解是,在第一个循环中初始化我的对象时,它们会超出范围并在每次循环迭代结束时死亡。

Correct. 正确。

If so, how do I make a persistent instance? 如果是这样,我如何创建持久化实例?

vector<>::push_back takes care of this. vector<>::push_back负责这个。 It copies the parameter into the vector. 它将参数复制到矢量中。 In other words, it's not the same object that was created in the loop, it's a copy. 换句话说,它与循环中创建的对象不同,它是一个副本。 You just need to ensure that ExampleClass has non-broken copy semantics. 您只需要确保ExampleClass具有非破坏的复制语义。

couldn't for the life of me work out how to dereference from an iterator of a shared_ptr<> 我不能为我的生活找出如何从shared_ptr <>的迭代器中取消引用

If you had an iterator into a vector of shared pointers, (call it it ), you would dereference it, and call the member function of the stored object, like this: 如果你有一个迭代到共享指针的向量,(称之为it ),你会解除引用它,并调用存储对象的成员函数,如下所示:

(*it)->performAction();
// alternatively
(**it).performAction();

The ideal answer suggests a very bad idea - use post increment ++ on iterator in loop. 理想的答案表明一个非常糟糕的想法 - 在循环中使用迭代器上的后增量++。 You should never ever use it in loops where you only need to iterate because postincrement must return the value the iterator had before it was incrementing; 你永远不应该在你只需要迭代的循环中使用它,因为postincrement必须返回迭代器在递增之前的值; so, that previous value needs to be copied somewhere before. 所以,以前的值需要先复制到某处。 It is just not good from performance perspective and a bad codestyle sign. 从性能角度和糟糕的代码风格标志来看,它并不好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM