C++ 对象向量与指向对象的指针向量 [英] C++ vector of objects vs. vector of pointers to objects

查看:45
本文介绍了C++ 对象向量与指向对象的指针向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 openFrameworks 编写应用程序,但我的问题不仅仅针对 oF;相反,这是一个关于 C++ 向量的一般问题.

I am writing an application using openFrameworks, but my question is not specific to just oF; rather, it is a general question about C++ vectors in general.

我想创建一个包含另一个类的多个实例的类,但也提供了一个直观的界面来与这些对象进行交互.在内部,我的类使用了类的向量,但是当我尝试使用 vector.at() 操作对象时,程序会编译但无法正常工作(在我的情况下,它不会显示视频).

I wanted to create a class that contains multiple instances of another class, but also provides an intuitive interface for interacting with those objects. Internally, my class used a vector of the class, but when I tried to manipulate an object using vector.at(), the program would compile but not work properly (in my case, it would not display a video).

// instantiate object dynamically, do something, then append to vector
vector<ofVideoPlayer> videos;
ofVideoPlayer *video = new ofVideoPlayer;
video->loadMovie(filename);
videos.push_back(*video);

// access object in vector and do something; compiles but does not work properly
// without going into specific openFrameworks details, the problem was that the video would
// not draw to screen
videos.at(0)->draw();

在某处,有人建议我制作一个指向该类对象的指针向量,而不是这些对象本身的向量.我实现了这一点,确实它很有魅力.

Somewhere, it was suggested that I make a vector of pointers to objects of that class instead of a vector of those objects themselves. I implemented this and indeed it worked like a charm.

vector<ofVideoPlayer*> videos;
ofVideoPlayer * video = new ofVideoPlayer;
video->loadMovie(filename);
videos.push_back(video);
// now dereference pointer to object and call draw
videos.at(0)->draw();

我正在为对象动态分配内存,即 ofVideoPlayer = new ofVideoPlayer;

I was allocating memory for the objects dynamically, i.e. ofVideoPlayer = new ofVideoPlayer;

我的问题很简单:为什么使用指针向量有效,以及何时创建对象向量与指向这些对象的指针向量?

My question is simple: why did using a vector of pointers work, and when would you create a vector of objects versus a vector of pointers to those objects?

推荐答案

我的问题很简单:为什么使用指针向量工作,以及何时你会创建一个对象的向量吗与指向那些指针的向量对象?

My question is simple: why did using a vector of pointers work, and when would you create a vector of objects versus a vector of pointers to those objects?

std::vector 就像一个用 new 分配的原始数组,当您尝试推入比当前大小更多的元素时重新分配.

std::vector is like a raw array allocated with new and reallocated when you try to push in more elements than its current size.

所以,如果它包含A 指针,就好像你在操作一个A* 的数组.当它需要调整大小时(你 push_back() 一个元素已经被填充到它的当前容量),它会创建另一个 A* 数组并复制到 A* 数组中code>A* 来自前一个向量.

So, if it contains A pointers, it's like if you were manipulating an array of A*. When it needs to resize (you push_back() an element while it's already filled to its current capacity), it will create another A* array and copy in the array of A* from the previous vector.

如果它包含 A 对象,那么就像你在操作一个 A 的数组,所以 A 应该是默认构造的,如果有是自动重新分配发生.在这种情况下,整个 A 对象也被复制到另一个数组中.

If it contains A objects, then it's like you were manipulating an array of A, so A should be default-constructible if there are automatic reallocations occuring. In this case, the whole A objects get copied too in another array.

看到区别了吗?如果您执行一些需要调整内部数组大小的操作,std::vector 中的 A 对象可以更改地址.std::vector 中包含对象的大多数问题来自哪里.

See the difference? The A objects in std::vector<A> can change address if you do some manipulations that requires the resizing of the internal array. That's where most problems with containing objects in std::vector comes from.

使用std::vector 而不会出现此类问题的一种方法是从一开始就分配一个足够大的数组.这里的关键字是容量". std::vector 容量是内存缓冲区的真实大小,它将在其中放置对象.因此,要设置容量,您有两种选择:

A way to use std::vector without having such problems is to allocate a large enough array from the start. The keyword here is "capacity". The std::vector capacity is the real size of the memory buffer in which it will put the objects. So, to setup the capacity, you have two choices:

1) 在构造时调整 std::vector 的大小,以从头开始构建所有对象,对象数量最多 - 这将调用每个对象的构造函数.

1) size your std::vector on construction to build all the object from the start , with maximum number of objects - that will call constructors of each objects.

2) 一旦 std::vector 被构造(但里面没有任何东西),使用它的 reserve() 函数:然后向量将分配一个足够大的缓冲区(您提供向量的最大大小).向量将设置容量.如果您在此向量中 push_back() 对象或 resize() 低于您在 reserve() 调用中提供的大小限制,它永远不会重新分配内部缓冲区,并且您的对象不会更改内存中的位置,从而使指向这些对象的指针始终有效(检查容量永远不会发生变化的断言是一种极好的做法).

2) once the std::vector is constructed (but has nothing in it), use its reserve() function : the vector will then allocate a large enough buffer (you provide the maximum size of the vector). The vector will set the capacity. If you push_back() objects in this vector or resize() under the limit of the size you've provided in the reserve() call, it will never reallocate the internal buffer and your objects will not change location in memory, making pointers to those objects always valid (some assertions to check that change of capacity never occurs is an excellent practice).

这篇关于C++ 对象向量与指向对象的指针向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆