我是一名专家级Java程序员,试图将我的知识转移到C ++。这不是家庭作业,只是一个我试图学习C ++等效的概念。
我正在尝试做的是使用循环“生成”自定义类型的对象列表。这就是我在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();
}
}
}
超级简单的东西。创建一个列表,遍历任意循环并向其添加对象。然后,遍历这些对象并将它们用于任何目的。
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:
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? */
}
}
我的理解是,在第一个循环中初始化我的对象时,它们会超出范围并在每个循环迭代结束时死掉。是对的吗?如果是这样,我如何创建持久化实例?
我尝试使用shared_ptr&lt;&gt;从而且显然能够持久存储它们,但是在我的生活中无法解决如何从shared_ptr&lt;&gt;的迭代器中取消引用。
我觉得这应该是一个非常简单的概念。我似乎无法解决这个问题。我已经阅读了很多关于C ++范围和循环的内容。我似乎无法在两者身上找到任何东西。
答案 0 :(得分:5)
ExampleObject obj;
_exampleObjects.push_back(obj);
/* What actually goes here in place of obj? */
无。假设ExampleClass
有一个工作副本构造函数,那么你所拥有的是正确的。如果您的编译器支持C ++ 11(并且因为您使用的是auto
,它至少部分地使用了它),您可以保存自己的副本。
_exampleObjects.emplace_back();
这会在向量中构造一个对象,将参数(在本例中为none)转发给匹配的构造函数(在本例中为默认的ctor)。要从迭代器访问对象,请执行以下操作:
for(auto it = _exampleObjects.begin(); it != _exampleObjects.end(); it++)
{
it->performAction();
}
同样,C ++ 11可以在这里做得更好。
for(auto & obj : _exampleObjects)
{
obj.performAction();
}
我的理解是我在第一个中初始化我的对象 循环,它们超出范围并在每次循环迭代结束时死亡。
正确。
如果是这样,我如何制作持久化实例?
vector<>::push_back
会解决这个问题。它将参数复制到矢量中。换句话说,它与循环中创建的对象不同,它是一个副本。您只需要确保ExampleClass
具有非破坏的复制语义。
不能为我的生活弄清楚如何解除引用 shared_ptr&lt;&gt;
的迭代器
如果你有一个迭代器进入共享指针的向量,(称之为it
),你可以取消引用它,并调用存储对象的成员函数,如下所示:
(*it)->performAction();
// alternatively
(**it).performAction();
答案 1 :(得分:1)
理想的答案表明一个非常糟糕的想法 - 在循环中使用迭代器上的后增量++。 你永远不应该在你只需要迭代的循环中使用它,因为postincrement必须返回迭代器在递增之前的值;所以,以前的值需要先复制到某处。 从性能角度和糟糕的代码风格标志来看,这是不好的。