【问题标题】:Returning an object or a pointer in C++在 C++ 中返回对象或指针
【发布时间】:2012-10-24 05:09:19
【问题描述】:

在 C++ 中,我的方法应该返回对象还是指向对象的指针?如何决定?如果是运营商呢?如何定义?

还有一件事——如果指针变成一个向量,我如何在返回后找出它的大小?如果这是不可能的,我认为它是,我应该如何继续正确返回一个没有这个限制的数组?

【问题讨论】:

    标签: c++ object pointers return-value


    【解决方案1】:

    在 C++ 中,我的方法应该返回对象还是指向对象的指针? 如何决定?

    从 C++11 开始,我们在 C++ 中使用了移动语义,这意味着它像以前一样简单,现在也可以快速按值返回。这应该是默认值。

    如果是运算符呢?如何定义?

    operator= 等许多运算符通常会返回一个 reference*this

    X& X::operator=(X rhs); 
    

    如果您想遵守通常的模式(而且您应该这样做),您需要为每个运算符查找它。从这里开始:Operator overloading

    正如 Ed S 所指出的,返回值优化也适用(甚至在 C++11 之前),这意味着您返回的对象通常不需要被复制或移动。

    所以,这就是现在返回东西的方式:

    std::string getstring(){ 
       std::string foo("hello");
       foo+=" world";
       return foo;
    }
    

    我在这里创建了一个 foo 对象的事实不是我的意思,即使你只是做了return "hello world"; 这是要走的路。

    还有一件事——如果指针变成一个向量,我怎么能 退货后找出它的尺寸?如果这是不可能的,就像我想的那样 是的,如果没有这个,我应该如何继续正确返回一个数组 限制?

    标准中的所有可复制或可移动类型也是如此(这些几乎是所有类型,例如vectorssets 等等),除了少数例外。例如 std::arrays 不会从移动中获益。它们花费的时间与元素的数量成正比。您可以在unique_ptr 中将其退回以避免复制。

    typedef std::array<int,15> MyArray;
    std::unique_ptr<MyArray> getArray(){ 
      std::unique_ptr<MyArray> someArrayObj(new MyArray());
      someArrayObj->at(3)=5;
      return someArrayObj;
    }
    
    int main(){
      auto x=getArray();
      std::cout << x->at(3) <<std::endl; // or since we know the index is right: (*x)[3]
    }
    

    现在,为了避免再写new(极少数情况下的专家除外),您应该使用名为make_unique 的辅助函数。这将极大地帮助异常安全,并且同样方便:

    std::unique_ptr<MyArray> getArray(){ 
      auto someArrayObj=make_unique<MyArray>();
      someArrayObj->at(3)=5;
      return someArrayObj;
    }
    

    要获得更多动力和make_unique 的(非常短的)实现,请看这里: make_unique and perfect forwarding

    更新

    现在make_unique 是 C++14 标准的一部分。如果你没有,你可以从proposal by S.T.L.:找到并使用整个实现

    Ideone example on how to do that

    【讨论】:

    • 甚至在移动语义之前,我们就有了 RVO,它支持跨翻译单元的 RVO。
    • return "hello"; 真的会破坏它吗?即返回值是否需要命名?
    • 当您知道索引没有超出范围时,无需使用std::array::at()
    • @EdS。没错,但作为一个例子,指针上[] 的语法不是很好;)
    • @JohanLundberg:我想我们只需要在那里不同意,但好吧,很公平。
    【解决方案2】:

    在 C++ 中,我的方法应该返回对象还是指向对象的指针?

    您应该默认返回一个对象。通常的例外是返回给定类的子类的函数,并且当不返回任何内容时是函数的合法选项1

    如果是运算符呢?

    运算符返回引用或对象;尽管从重载运算符返回指针在技术上是可行的,但通常不会这样做。

    还有一件事——如果指针变成了一个向量,我如何才能知道它返回后的大小?

    我认为您的意思是 array 而不是 vector,因为 std::vector 有一个 size() 成员函数返回向量的大小。确实不可能找到变长数组的大小。

    如果我认为不可能,我应该如何继续正确返回一个没有此限制的数组?

    您应该使用std::vector,它不会限制您进入其中的元素的大小或类型。


    1 在这种情况下,您在 C++11 中返回 NULLnullptr

    【讨论】:

      【解决方案3】:

      除非有特定原因使用普通指针,否则总是返回内存安全的东西。在大约 95% 的情况下,简单地返回对象就可以了,然后按值返回绝对是规范的做法(简单、高效、好!)。

      剩下的 5% 主要是返回的对象是运行时多态的;这样的对象不能在 C++ 中按值返回,因为这会发生在堆栈上。在这种情况下,您应该返回一个指向新对象的智能指针,在 C++11 中,标准选择是std::unique_ptr。还有一种情况是您希望可选地返回一些东西,但这是 IMO 特定容器的情况,而不是指针,boost::optionalsomething like that

      【讨论】:

      • HASKELLLIKE_CLASS_MAYBE_MONAD 是一个非常可爱的名字。
      猜你喜欢
      • 1970-01-01
      • 2011-10-03
      • 2020-05-15
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 2016-06-10
      相关资源
      最近更新 更多