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

2021-12-08 00:00:00 return performance reference c++

我知道标题听起来很熟悉,因为有很多类似的问题,但我要问的是问题的不同方面(我知道把东西放在堆栈上和把它们放在堆上的区别).

I know the title sounds familiar as there are many similar questions, but I'm asking for a different aspect of the problem (I know the difference between having things on the stack and putting them on the heap).

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

In Java I can always return references to "local" objects

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

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

In C++, to do something similar I have 2 options

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

(1) I can use references whenever I need to "return" an object

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

然后像这样使用

Thing thing;
calculateThing(thing);

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

(2) Or I can return a pointer to a dynamically allocated object

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

然后像这样使用

Thing* thing = calculateThing();
delete thing;

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

Using the first approach I won't have to free memory manually, but to me it makes the code difficult to read. The problem with the second approach is, I'll have to remember to delete thing;, which doesn't look quite nice. I don't want to return a copied value because it's inefficient (I think), so here come the questions

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

推荐答案

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

I don't want to return a copied value because it's inefficient

证明它.

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

Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.

只需编写干净的代码,按值返回.如果性能是一个问题,请对其进行分析(停止猜测),并找出您可以采取的措施来解决它.它可能不会从函数中返回内容.

Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.

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

That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.

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

If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!

相关文章