向量添加对象与在c ++中添加向量指针?

时间:2013-05-29 14:58:35

标签: c++

在向量中添加对象,在c ++中添加指向向量的指针。

示例:

std::vector<Size> buildings;
Size building(buildingWidth, buildingHeight);
buildings.push_back(building);

VS

std::vector<Size*> buildings;
Size *building = new Size(buildingWidth, buildingHeight);
buildings.push_back(building);

哪一个在内存/性能方面更好?

第一个基本上在堆栈上创建一个对象并将其添加到向量中。 所以有一个实例化,然后一个副本进入向量。

第二个在堆上创建一个对象。 有一个实例,但向量中没有副本。

我说错了吗?

6 个答案:

答案 0 :(得分:4)

这两种存储技术有不同的用途。

第一种技术对于“同质”向量非常有用,您不需要多态行为,并且对象切片不是问题。您可以获得自动资源管理:您无需担心对象的所有权,因为向量会生成副本。每次调整矢量大小时,也会在内部制作副本。当复制对象有点昂贵时,这种考虑使得第一选项不那么有吸引力;您需要对代码进行分析,以确定此代价是否适用于此代码。

第二种技术将管理内存的责任放在你身上:每当你决定从你的指针向量中删除一个对象时,你需要获得所有权,并最终明确地delete该对象。您可以使用智能指针来解决资源管理问题。这种技术可以避免复制,但访问容器内元素的过程变得更加复杂。

答案 1 :(得分:0)

它们通常具有相对相似的性能,具体取决于对象的对象大小和复制语义。 关于内存泄漏和可用性,第一种方法通常要好得多。

答案 2 :(得分:0)

这实际上取决于尺寸的性质。如果对象很大(只要复制构造函数必须做很多工作),那么你可以考虑你的指针想法。但是你必须自己控制内存,不管你做什么,都不要继承std :: vector,因为继承标准容器不是一个好主意(一方面它们没有虚拟析构函数)!

您可以在Size类中构建一些写入语义的副本(有点像std :: string的实现)。

或者有一个默认的构造函数和一个Size的swap方法(你需要在std :: vector中使用默认的构造函数)。使用swap方法将新的Size对象交换到向量中的位置。

基于“过早优化是所有邪恶的根源”(归因于Tony Hoare),我坚持使用最简单的方法;即你的第一个想法,看看它是怎么回事。

答案 3 :(得分:0)

真的归结为

  • 将对该向量执行哪些操作
  • 将对象推送到矢量的频率

如果您要对向量进行任何类型的可变操作,那么最好使用shared_ptr类型。

最终,对于任何与性能相关的问题,最好在您的应用条件下自行测试。

答案 4 :(得分:0)

为什么不这样做:

std::vector<Size> buildings;
buildings.resize(1);
buildings[0].setSize(buildingWidth, buildingHeight);

这样构造函数只调用一次,您不必自己管理内存。我能想到的唯一缺点是宽度和高度设置两次(一次在构造函数中,一次在“setSize”中),但我不认为你可以摆脱它,除非你使用std::vector<Size *>方法

答案 5 :(得分:-1)

我认为使用指针向量的第二种方法是两种选择中的更好。由于两个简单的原因

  1. 如果对象大小较大,那么使用对象向量会增加不必要的复制。
  2. 如果您将对象向量作为参数传递给方法,然后尝试修改向量中的任何对象,那么它将不会在所有位置反映出来。