在C++中解决复制语义问题

15

请考虑以下代码:

class A
{

};

int main()
{
    std::vector<A> test;
    test.push_back(A());
}

构造函数和析构函数将被调用两次,还会分配两次内存并复制对象,这不仅可能对性能有潜在的负面影响,而且还可能导致运行时错误,特别是如果析构函数中存在一些清理操作。我通常的解决方法是只创建指针的向量:

std::vector<A*> test;
test.push_back(new A());

我的问题有两个方面,这是常见做法吗?是否是优秀的做法?还是有更好的方法?如果这已经是重复问题,请告诉我,我会关闭这个问题,但我在搜索中找不到任何相关结果。


7
不使用指针是常见做法,而且不使用指针是个好习惯。如果您不使用指针并实现一个"移动"构造函数,那么这将是更好的做法。 - Some programmer dude
4
在这种情况下,智能指针是否更加合适?至少只要vector需要拥有这些对象。 - Dan Mašek
这些微小的优化通常不会给你带来值得付出努力去实现它们的好处。 - Dietrich Epp
@DietrichEpp 对,最好先让它工作,然后再进行优化。但下面的好答案不需要太多的努力,如果对象很大的话可以节省时间(例如:固定长度的向量向量)。 - Jean-François Fabre
3
这并不是一种微小的优化,而且 emplace_back 使得优化变得非常简单。 - asu
显示剩余7条评论
1个回答

25

使用emplace_back

std::vector<A> test;
test.emplace_back();
//test.emplace_back(constructor, parameters);

这样,A 将会就地构建,因此不会发生复制或移动。

编辑:为了澄清对问题的评论 - 不,如果你传递一个临时对象给 push_back,它不会发生变化。例如,

test.emplace_back(A{});

在C++11中,使用emplace_back将会构造、移动和销毁一个临时对象A,就像你使用push_back一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接