创建 C++ 指针向量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20158793/
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 22:55:57  来源:igfitidea点击:

Creating c++ vector of pointers

c++pointersvector

提问by Parzival

In my C++ code I have a class Object equipped with an id field of type int. Now I want to create a vector of pointers of type Object*. First I tried

在我的 C++ 代码中,我有一个类 Object,它配备了一个 int 类型的 id 字段。现在我想创建一个 Object* 类型的指针向量。首先我试过

vector<Object*> v;

for(int id=0; id<n; id++) {
    Object ob = Object(id);
    v.push_back(&ob);
}

but this failed because here the same address just repeats itself n times. If I used the new operator I would get what I want but I'd like to avoid dynamic memory allocation. Then I thought that what I need is somehow to declare n different pointers before the for loop. Straightforward way to this is to declare an array so I did this :

但这失败了,因为这里相同的地址只是重复了 n 次。如果我使用 new 运算符,我会得到我想要的,但我想避免动态内存分配。然后我想我需要的是在 for 循环之前以某种方式声明 n 个不同的指针。直接的方法是声明一个数组,所以我这样做了:

vector<Object*> v;
Object ar[n];

for(int i=0; i<n; i++) {
    ar[i] = Object(i);
}

for(int i=0; i<n; i++) {
    v.push_back(ar+i);
}

Is there still possibility to get a memory leak if I do it this way? Also going through an array declaration is a bit clumsy in my opinion. Are there any other ways to create vector of pointers but avoid manual memory management?

如果我这样做,还有可能发生内存泄漏吗?在我看来,通过数组声明也有点笨拙。有没有其他方法可以创建指针向量但避免手动内存管理?

EDIT: Why do I want pointers instead of just plain objects?

编辑:为什么我需要指针而不是普通对象?

Well I modified the original actual situation a bit because I thought in this way I can represent the question in the simplest possible form. Anyway I still think the question can be answered without knowing why I want a vector of pointers.

那么我对原来的实际情况做了一点修改,因为我认为这样我可以用最简单的形式来表达问题。无论如何,我仍然认为可以在不知道为什么我想要一个指针向量的情况下回答这个问题。

Actually I have

其实我有

Class A {
protected:
    vector<Superobject*> vec;
...
};

Class B: public A {...};

Class Superobject {
protected:
    int id;
...
}

Class Object: public Superobject {...}

In derived class BI want to fill the member field vecwith objects of type Object. If the superclass didn't use pointers I would have problems with object slicing. So in class Bconstructor I want to initialize vecas vector of pointers of type Object*.

在派生类中,B我想vec用类型的对象填充成员字段Object。如果超类不使用指针,我就会遇到对象切片的问题。所以在类B构造函数中,我想初始化vec为类型指针的向量Object*

EDIT2

编辑2

Yes, it seems to me that dynamic allocation is the reasonable option and the idea to use an array is a bad idea. When the array goes out of scope, things will go wrong because the pointers in vector point to memory locations that don't necessarily contain the objects anymore.

是的,在我看来动态分配是合理的选择,而使用数组的想法是个坏主意。当数组超出范围时,事情就会出错,因为 vector 中的指针指向不一定包含对象的内存位置。

In constructor for class B I had

在类 BI 的构造函数中有

B(int n) {
    vector<Object*> vec;
    Object ar[n];

    for(int id=0; id<n; id++) {
        ar[id] = Object(id);
    }

    for(int id=0; id<n; id++) {
        v.push_back(ar+id);
    }
 }

This caused very strange behavior in objects of class B.

这在 B 类对象中引起了非常奇怪的行为。

回答by marcinioski

In this loop:

在这个循环中:

for(int id=0; id<n; id++) {
    Object ob = Object(id);
    v.push_back(&ob);
}

You are creating n times Object instance on stack. At every iteration there is created and removed element. You can simply avoid this using that:

您正在堆栈上创建 n 次 Object 实例。每次迭代都会创建和删除元素。您可以简单地使用它来避免这种情况:

for(int id=0; id<n; id++) {
    Object* ob = new Object(id);
    v.push_back(ob);
}

thanks that every new element exist on heap not on the stack. Try to add to in class Object constructor something like that:

感谢每个新元素都存在于堆上而不是堆栈上。尝试在类 Object 构造函数中添加类似的内容:

std::cout<<"Object ctor()\n";

and the same in the destructor:

在析构函数中也是如此:

std::cout<<"Object dtor()\n";

If you dont want to create these objects with "new" try reason written by @woolstar

如果您不想使用@woolstar 编写的“新”尝试创建这些对象

回答by woolstar

Your question about memory leaks makes me think you are worried about the lifecycle and cleanup of these objects. I originally proposed shared_ptrwrappers, but C++11 gave us unique_ptr, and C++14 filled in the missing make_unique. So with all that we can do:

你关于内存泄漏的问题让我觉得你担心这些对象的生命周期和清理。我最初提出了shared_ptr包装器,但 C++11 给了我们unique_ptr,而 C++14 填补了缺失的make_unique. 尽我们所能:

vector<unique_ptr<SuperObject>> v ;

Which you create in place with the wonderfulness of perfect forwarding and variadic templates,

您使用完美转发和可变参数模板的美妙之处就地创建,

v.push_back( make_unique<Object>( ... ) ) ;

Yes you are going to have to live with some heap allocations, but everything will be cleaned up when vgoes away.

是的,您将不得不忍受一些堆分配,但是一切都将在v消失时清理干净。

Someone proposed a boost library, ptr_container, but that requires not only adding boost to your project, but educating all future readers what this ptr_containeris and does.

有人提出了一个 boost 库,ptr_container但这不仅需要为你的项目添加 boost,还需要教育所有未来的读者这ptr_container是什么,做什么。

回答by Machtl

No there is no memory leak in your version. When the program leaves your scope the vector as well the array are destroyed. To your second question: Why not simply store the objects directly in an vector?

不,您的版本中没有内存泄漏。当程序离开您的作用域时,向量和数组都会被销毁。对于您的第二个问题:为什么不简单地将对象直接存储在向量中?

vector<Object> v;

for(int i = 0; i < n; i++)
{
    Object obj = Object(i);
    v.push_back(obj);
}