5

可能重复:
如何在 C++ 中“返回一个对象”

大家好!

如果我需要从函数返回一个对象(而且它不是getter,而且由于某种原因这个函数不能作为构造函数实现,例如有一个具有相同签名和不同语义的构造函数),如何更好地实现这个?

例如,可以提出以下选项:

1)返回一个对象本身:

MyClass GetMyClass() {
    MyClass a;
    ...
    return a;
}

在大多数情况下,RVO会执行http://en.wikipedia.org/wiki/Return_value_optimization,不会调用复制构造函数,也不会产生开销。这种方法的缺点是,尽管有 RVO,但您必须指定 MyClass 的复制构造函数,但正如 Google C++ Style Guide 中所述...

C++ 中对象的隐式复制是错误和性能问题的丰富来源。

2) 返回指向对象的指针:

MyClass* GetMyClass() {
    MyClass* a= new MyClass();
    ...
    return a;
}

在这种情况下,由于在堆上分配内存会产生开销。由于 malloc 系统调用,这以某种方式减慢了程序的速度。此外,您应该在此函数之外释放内存,这意味着分配和释放在不同的逻辑单元中执行。如此处所述,为什么函数中的 malloc 内存并在外部释放它是一个坏主意?这通常是一个坏主意。

3)通过引用或指针传递值:

void GetMyClass(MyClass& a) {
    ...
}

在这种情况下,代码变得丑陋且可读性差

最佳做法是什么?你在你的项目中使用哪一个?当你在一个大项目上工作时,哪些标准是最重要的?

4

2 回答 2

4

二是非常简单。是的, malloc 可能会很慢,但是对您来说有关系吗?您需要从某个地方为该对象提供空间。另请注意您指出的问题中的答案,只有跨逻辑单元才会出现问题。看看你是否有问题,然后尝试修复它而不是预先优化。

您可能会制作自己的 new 版本,该版本使用免费商店并自行管理资源。但是,除非您已经测量并发现新问题是一个问题,否则它很容易出错。

一种可以帮助改善释放指针问题的方法是使用std::shared_ptr。这样你就不必担心释放对象,只要你总是通过智能指针使用它。

于 2012-11-02T20:11:25.853 回答
2

您忽略了返回移动可构造对象的明显机会:在许多情况下,返回值可能仍会减少开销,但您不会冒意外复制的风险。在 C++ 2011 不可用的地方,我会让类型可复制并按值返回。

如果移动和复制都不是一个选项,我会返回一个指针。当然,我不会返回一个裸指针,而是一个std::unique_ptr<T>(或std::auto_ptr<T>在不可用的情况下):使用智能指针可以避免内存泄漏的风险,但是选择轻量级指针而不是例如 ,std::shared_ptr<T>并不能做出最终的策略决定关于如何维护对象。在需要以某种有趣的方式释放对象的情况下,它可能带有一个删除器。

于 2012-11-02T20:13:03.733 回答