小编典典

如何在 C++ 中“返回一个对象”?

all

我知道标题听起来很熟悉,因为有很多类似的问题,但我问的是问题的不同方面(我知道将事物放在堆栈上和将它们放在堆上之间的区别)。

在 Java 中,我总是可以返回对“本地”对象的引用

public Thing calculateThing() {
    Thing thing = new Thing();
    // do calculations and modify thing
    return thing;
}

在 C++ 中,做类似的事情我有 2 个选项

(1) 当我需要“返回”一个对象时,我可以使用引用

void calculateThing(Thing& thing) {
    // do calculations and modify thing
}

然后像这样使用它

Thing thing;
calculateThing(thing);

(2) 或者我可以返回一个指向动态分配对象的指针

Thing* calculateThing() {
    Thing* thing(new Thing());
    // do calculations and modify thing
    return thing;
}

然后像这样使用它

Thing* thing = calculateThing();
delete thing;

使用第一种方法我不必手动释放内存,但对我来说它使代码难以阅读。第二种方法的问题是,我必须记住 to delete thing;,这看起来不太好。我不想返回复制的值,因为它效率低下(我认为),所以问题来了

  • 是否有第三种解决方案(不需要复制值)?
  • 如果我坚持第一个解决方案有什么问题吗?
  • 何时以及为什么应该使用第二种解决方案?

阅读 169

收藏
2022-07-28

共1个答案

小编典典

我不想返回复制的值,因为它效率低下

证明给我看。

查找 RVO 和 NRVO,以及 C0x 移动语义。在 C03 中的大多数情况下,out 参数只是让代码变得丑陋的好方法,而在 C++0x 中,使用
out 参数实际上会伤害自己。

只需编写干净的代码,按值返回。如果性能是一个问题,请对其进行分析(停止猜测),然后找出可以解决的方法。它可能不会从函数返回东西。


就是说,如果你死心塌地那样写,你可能想要做 out
参数。它避免了动态内存分配,这更安全且通常更快。它确实需要您在调用函数之前有某种方法来构造对象,这并不总是对所有对象都有意义。

如果要使用动态分配,至少可以将其放入智能指针中。(无论如何都应该这样做)然后你不用担心删除任何东西,事情是异常安全的,等等。唯一的问题是它可能比按值返回慢!

2022-07-28