在向量中添加对象,在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);
哪一个在内存/性能方面更好?
第一个基本上在堆栈上创建一个对象并将其添加到向量中。 所以有一个实例化,然后一个副本进入向量。
第二个在堆上创建一个对象。 有一个实例,但向量中没有副本。
我说错了吗?
答案 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)
我认为使用指针向量的第二种方法是两种选择中的更好。由于两个简单的原因