c ++类对象指针的向量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1798631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:11:05  来源:igfitidea点击:

c++ vector of class object pointers

c++classreferencevectorpointers

提问by Nigel

What I am trying to do is essentially create two vectors of objects, where some objects are entered into both lists and some are just entered into one. The first problem I found was that when I used push_back() to add an object into both lists the object was copied so that when I changed it from one list the object did not change in the other. To get around this I tried to create a list of pointers to objects as one of the lists. However when I accessed the pointer later on the data seemed to be corrupted, the data member values were all wrong. Here are some snippets of my code:

我想要做的本质上是创建两个对象向量,其中一些对象被输入到两个列表中,而有些对象只是输入到一个列表中。我发现的第一个问题是,当我使用 push_back() 将对象添加到两个列表中时,对象被复制,因此当我从一个列表更改它时,对象在另一个列表中没有更改。为了解决这个问题,我尝试创建一个指向对象的指针列表作为列表之一。但是,当我稍后访问指针时,数据似乎已损坏,数据成员值全都错误。以下是我的一些代码片段:

Definition of vectors:

向量的定义:

vector<AbsorbMesh> meshList;
vector<AbsorbMesh*> absorbList;

... Adding an object to both:

... 向两者添加一个对象:

AbsorbMesh nurbsMesh = nurbs.CreateMesh(uStride, vStride);

// Add to the absorption list
absorbList.push_back(&nurbsMesh);
// Store the mesh in the scene list
meshList.push_back(nurbsMesh);

Accessing the object:

访问对象:

if (absorbList.size() > 0)
{
float receivedPower = absorbList[0]->receivedPower;
}

What am I doing wrong?

我究竟做错了什么?

回答by Glen

There's some details missing, but at a guess.

缺少一些细节,但可以猜测。

nurbsMeshgoes out of scope between the push_backand the absorbList[0]->receivedPower.

nurbsMesh超出了push_back和之间的范围absorbList[0]->receivedPower

So now your vector of pointers contains a pointer to an object that doesn't exist anymore.

所以现在你的指针向量包含一个指向不再存在的对象的指针。

Try adding a copy constructor to your AbsorbMesh class and adding to your vector like this.

尝试向您的 AbsorbMesh 类添加一个复制构造函数,并像这样添加到您的向量中。

absorbList.push_back(new AbsorbMesh(nurbsMesh));
meshList.push_back(nurbsMesh);

don't forget to delete the objects in absorbList, like this

不要忘记删除中的对象absorbList,像这样

for(vector<AbsorbMesh*>::iterator it = absorbList.begin(); it != absorbList.end(); it++) {
    delete it;
  }

Or store a shared pointer in your vector instead of a bare pointer. Boost has a good shared pointer implementation if you're interested. See the docs here

或者在你的向量中存储一个共享指针而不是一个裸指针。如果您感兴趣,Boost 有一个很好的共享指针实现。请参阅此处的文档

If you want to have updates to items in one vector modify objects in the other vector, then you'll need to store pointers in both vectors.

如果您希望对一个向量中的项目进行更新并修改另一个向量中的对象,那么您需要在两个向量中存储指针。

Using your original requirements (updating an item in one vector affects items in the other vector, here's how I'd do it with a boost shared pointer. (WARNING, untested code)

使用您的原始要求(更新一个向量中的项目会影响另一个向量中的项目,这是我使用 boost 共享指针的方法。(警告,未经测试的代码)

vector<boost::shared_ptr<AbsorbMesh> > meshList;
vector<boost::shared_ptr<AbsorbMesh> > absorbList;

boost::shared_ptr<AbsorbMesh> nurb = new AbsorbMesh(nurbs.CreateMesh(uStride, vStride));

meshList.push_back(nurb);
absorbList.push_back(nurb);

...
...

if (absorbList.size() > 0)
{
    float receivedPower = absorbList[0].get()->receivedPower;
}

回答by Naveen

You are storing the address of an object allocated on stack. The nurbsMeshobject gets destroyed as soon as your method which does push_back()ends. If you try to access this pointer afterwards the object is already destroyed and contains garbage. What you need is to retain the object which remains even after the function goes out of scope. To do this allocate the memory for the object from heap using new. But for every new you should have a corresponding delete. But in your case you'll have problems deleting it as you are pushing the same pointer into two vectors. To solve this, you would require some type reference counting mechanism.

您正在存储在堆栈上分配的对象的地址。nurbsMesh一旦你的方法push_back()结束,对象就会被销毁。如果您之后尝试访问此指针,则该对象已被销毁并包含垃圾。您需要的是保留即使在函数超出范围之后仍然存在的对象。为此,使用new. 但是对于每一个新的你应该有一个对应的delete. 但是在您的情况下,当您将同一指针推入两个向量时,删除它会遇到问题。为了解决这个问题,您需要某种类型引用计数机制。

回答by Staseg

Object is deleted when you try get pointer from vector.

当您尝试从向量中获取指针时,对象被删除。

Try do

尝试做

vector.push_back(new Object);

回答by Thomas

Once you have fixed the problem that others mentioned (storing a pointer to an object that's on the stack), you're going to run into another issue. A vectormay reallocate, which results in its contents moving to another location.

一旦您解决了其他人提到的问题(存储指向堆栈上的对象的指针),您将遇到另一个问题。Avector可能会重新分配,这会导致其内容移动到另一个位置。

The safe way to do this, then, is to store pointers in bothvectors. Then, of course, you need to ensure that they get deleted... but that's C++ for you.

那么,这样做的安全方法是将指针存储在两个向量中。然后,当然,您需要确保它们被删除……但这对您来说是 C++。

回答by ChrisW

However when I accessed the pointer later on the data seemed to be corrupted

但是,当我稍后访问指针时,数据似乎已损坏

When you put something on a vector, the vector might move it from one physical location to another (especially e.g. when the vector is resized), which invalidates any pointer to that object.

当您将某物放在向量上时,向量可能会将其从一个物理位置移动到另一个物理位置(尤其是当向量被调整大小时),这会使指向该对象的任何指针无效。

To fix that, you'll need to store a pointer (possibly a 'smart pointer') in both vectors (instead of having one vector contain the object by value).

要解决这个问题,您需要在两个向量中存储一个指针(可能是一个“智能指针”)(而不是让一个向量按值包含对象)。

If you're going to do this, it might be a good idea to disable the object's copy constructor and assignment operator (by declaring them as private, and not defining them) to ensure that after an object is created it cannot be moved.

如果您打算这样做,最好禁用对象的复制构造函数和赋值运算符(通过将它们声明为私有,而不是定义它们)以确保在创建对象后无法移动它。

回答by Sebastian

There are several things wrong with your example

你的例子有几个问题

AbsorbMesh nurbsMesh = nurbs.CreateMesh(uStride, vStride);

This object is allocated on the stack. It is a purely local object. This object is going to be destroyed when you reach the end of the current block surrounded by {}.

该对象在堆栈上分配。它是一个纯粹的本地对象。当您到达由 {} 包围的当前块的末尾时,该对象将被销毁。

absorbList.push_back(&nurbsMesh);

Now you get the pointer to the object that most likely will be destroyed.

现在您获得了指向最有可能被销毁的对象的指针。

meshList.push_back(nurbsMesh)

And this copies an entirely new object on the vector.

这会在向量上复制一个全新的对象。

It is equally wrong to push the object on the vector first and then push a pointer to the object on the vector using absorbList.push_back( &meshList.back() )because vector::push_backwill reallocate the whole vector, invalidating all pointers.

首先将对象推送到向量上,然后将指针推送到向量上的对象,这同样是错误的,absorbList.push_back( &meshList.back() )因为vector::push_back会重新分配整个向量,使所有指针无效。

You might be able to create all AbsorbMeshobjects first, push them onto a vector, and then get the pointers to these objects in the vector. As long as you don't touch the vector, you'll be fine.

您可能能够创建所有AbsorbMesh第一对象,他们推到一个载体,然后拿到三分对这些对象的向量。只要你不接触矢量,你就没事。

Alternatively, create objects on the heap using new AbsorbMesh()but make sure to call deleteon each pointer thus created. Otherwise you have a memory leak.

或者,在堆上创建对象, new AbsorbMesh()但请确保调用delete由此创建的每个指针。否则你有内存泄漏。

Third solution, avoid the trouble and use smart pointersthat take care of object destruction for you.

第三个解决方案,避免麻烦并使用为您处理对象销毁的智能指针

回答by David Thornley

First, as everybody else points out, you can't allocate objects on the stack (i.e., other than by newor something similar), and have them around after leaving the scope.

首先,正如其他人所指出的,你不能在堆栈上分配对象(即,除了 bynew或类似的东西),并在离开作用域后让它们在周围。

Second, having objects in an STL container and maintaining pointers to them is tricky, since containers can move things around. It's usually a bad idea.

其次,在 STL 容器中拥有对象并维护指向它们的指针很棘手,因为容器可以移动事物。这通常是一个坏主意。

Third, auto_ptr<>simply doesn't work in STL containers, since auto_ptrs can't be copied.

第三,auto_ptr<>在 STL 容器中根本不起作用,因为无法复制 auto_ptrs。

Pointers to independently allocated objects work, but deleting them at the right time is tricky.

指向独立分配对象的指针有效,但在正确的时间删除它们很棘手。

What will probably work best is shared_ptr<>. Make each vector a vector<shared_ptr<AbsorbMesh> >, allocate through new, and at a slight cost in performance you avoid a whole lot of hassle.

可能效果最好的是shared_ptr<>. 使每个向量 a vector<shared_ptr<AbsorbMesh> >,分配通过new,并以轻微的性能成本避免很多麻烦。

回答by Alexey Malistov

absorbList.push_back(&nurbsMesh);is wrong

absorbList.push_back(&nurbsMesh);是错的

absorbListsave pointer to local object. When nurbMeshis destroyed you can not write absorbList[0]->

absorbList保存指向本地对象的指针。什么时候nurbMesh销毁就不能写 absorbList[0]->