【发布时间】:2012-07-24 15:09:26
【问题描述】:
考虑下面的代码。
// Consider that MyObject receives three integers in it's constructor.
MyObject createObject()
{
MyObject result(1, 2, 3);
return result;
}
据我所知,当您在 C++ 中返回一个对象时(就像在这个函数中一样),编译器会在堆栈中为客户端创建一个新对象(作为局部变量)。在这个例子中,它将是一个新的MyObject 对象,它将使用复制构造函数以result 作为参数创建。这意味着机器的冗余处理:对象result 将在堆栈中创建,然后将创建并返回第二个对象。
避免这种情况的另一种方法是动态创建对象(不在堆栈中),然后返回它的指针。但这会导致内存泄漏或强制客户端在使用后删除对象。因此,我找到的解决方案是使用智能指针,如下所示:
// Consider that MyObject receives three integers in it's constructor.
boost::smart_ptr<MyObject> createObject()
{
boost::smart_ptr<MyObject> result(new MyObject(1, 2, 3));
return result;
}
这可行,但智能指针仍然是一个将被重新创建的对象(即使成本很低,因为基本上它只包含一个指针)。我在猜测是否有一种方法可以更轻松地做到这一点;或者如果编译器还没有实现优化这项工作的方法或类似的东西。有没有语法告诉编译器做我想做的事?
【问题讨论】:
-
是的,请务必阅读 RVO。不,如果您追求性能,请不要使用智能指针(分配可能比任何可能的副本花费更多)。而且您通常可以只要求调用者分配并传入一个非常量引用(丑陋但有效)。
-
@Keith 但随后分配给参数相当于复制它...
-
除非对象有外部资源,否则你无法真正优化它。如果是这样,C++11 将注意一个简单的返回将移动本地对象。如果对象是扁平的(也就是没有指向外部资源的指针/句柄),我会简单地获取副本,如果它来了,它应该不会花费太多(你不想拥有大的扁平对象,担心低效返回仅与具有外部资源的类型一起提供)。
-
@Luchian:如果它有外部资源,它可以有一种方法从另一个对象“窃取”,即使在没有移动语义的 C++03 中,通过显式请求它(如
result_ref.take_from(other)) .或者你甚至可以使用result_ref来做你想做的一切。 -
过早优化。使用最简单最易维护的方法(第一个版本)。只有当它很慢时才尝试优化并且您可以测量它,以便您可以将它与尝试的优化进行比较。如果你这样做,我敢打赌共享指针在很多情况下可能会更慢。
标签: c++ optimization object compiler-construction return