管理STL矢量中的作用域和对象生存期

Managing Scope and Object Lifetime Within STL Vectors

本文关键字:作用域 对象 生存期 STL 管理      更新时间:2023-10-16

我来自C#世界,我正在努力确保我不会在分配给我的C++项目中引入内存泄漏和错误。我正在编写使用structs从数据缓冲区解析信息的代码。由于缓冲区中出现的数据结构的数量在运行时可能会有所不同,因此使用stl向量来存储处理后的数据。我在现有软件中遇到了以下代码块,我很难理解它为什么有效:

MyVectorOfObjects.clear();
for (unsigned __int8 i = 0; i < NumberOfObjects; i++)
{
    MyParserObject parserObject;                // Declaring without 'new'?
    parserObject.Decode(buffer, offset, size);  // A method on the struct.
    MyVectorOfObjects.push_back(parserObject);  // Does this keep parserObject in scope?
}

我的问题具体如下:

  1. 根据这个问题,由于没有使用new关键字,parserObject不会在每次迭代中都超出范围吗?显然,这个代码一直在工作。

  2. 在这种情况下,将对象放置在vector中是否会使parserObject保持在作用域中?

  3. 根据这个问题,parserObject被复制。如果是这样的话,这会对性能产生什么影响(例如内存消耗、内存分配等(?此外,复制的parserObjects是否假定与向量的作用域相同?

谢谢你的帮助。

  1. 是的,每次循环迭代时,在for循环中声明的parserObject实例都会超出范围。

  2. 不,将parserObject放入vector中并不能将该对象保留在作用域中。push_back()方法将复制该对象,该对象现在归vector所有。您需要确保您的对象可以正确复制(复制构造函数和赋值运算符可能是必要的(。本例中矢量中包含的副本归矢量所有,其对象寿命与vector本身类似。

  3. paserObject被复制,这可能会对内存使用和性能产生影响。如果parserObject对于复制来说不是微不足道的,那么这可能是一个昂贵的操作。这完全取决于您对parserObject的实施。

MyVectorOfObjects.push_back(parserObject);  // Does this keep parserObject in scope?

push_back复制对象并存储它

因此,如果类MyParserObject具有指针成员,请确保为其正确定义了复制构造函数(和复制赋值(。否则,编译器生成的默认代码就足够了,前提是MyParserObject的每个成员都遵循相同的模式(即,如果它们有指针成员,则它们已经正确定义了复制构造函数(和复制赋值((,否则,编译器生成的默认代码也就足够了。。。。等等。(