C ++返回一个对象副本

时间:2012-05-30 14:26:04

标签: c++ optimization copy copy-constructor rvo

我写了以下代码:

class MyObjectHolder {
public:
    std::vector<int> getMyObject() const {
        return myObject;
    }

private:
    std::vector<int> myObject;
};

在我的程序的某些时候,我尝试使用getMyObject方法,并在检索到的对象上仅使用const方法:

const std::vector<int> myObject = myObjectHolder.getMyObject();
myObject.size();
int a = myObject.front();
  • 现在,编译器是否有可能优化此代码,以便没有std::vector<int> 的副本完成?

      

    编译器是否有可能确定我只在检索到的对象上使用const方法(并假设其背后没有发生mutable无意义)并且不会制作任何副本并在const的{​​{1}}成员上执行这些private操作?

  • 如果是,如果我没有明确声明MyObjectHolderconst std::vector<int> myObject,是否可以?

  • 如果不是,不这样做的原因是什么?在这种情况下,这种优化将难以实现/推断它可能并且在这里更正/等...?

3 个答案:

答案 0 :(得分:6)

  

现在,编译器是否有可能优化此代码,以便不会完成std::vector<int>的副本?

不,编译器不知道调用者将对该对象做什么,除非您对使用该对象的所有代码使用全局优化(编译器通常不能对其使用进行假设;此外,如果对象是从dll导出它根本不能做出任何假设。)

  

如果是,如果我没有明确地将const std :: vector myObject声明为const,那么可能吗?

不,无论如何,从非const到const的转换可能是隐含的。

  

如果不是,不这样做的原因是什么?在哪些情况下,这种优化将难以实现/推断它可能并且在这里更正/等...?

这是一个可以在getMyObject()内完成的optmiziation,但编译器无法确定调用者是否会抛弃const。实际上这是关于const使用的一个非常古老的争论,通常我认为总是将const视为程序员而非编译器的事情更为明确。

答案 1 :(得分:3)

我建议使用

const std::vector<int>& getMyObject() const {
    return myObject;
}

它会返回myObject的常量引用,而不会复制。

并将结果与​​

一起使用
const std::vector<int>& myObject = myObjectHolder.getMyObject();

答案 2 :(得分:0)

有可能Copy ElisionReturn Value Optimization会启动。如果您使用带有C++11支持的C ++编译器,那么您可以通过move semantics优化它。

我建议阅读Dave Abrahams撰写的优秀文章Want Speed? Pass by Value,并在下面的评论中进行讨论。

但是,有关详细信息,请参阅C ++编译器的文档。