【问题标题】:C++ Returning a Reference of an ObjectC++ 返回对象的引用
【发布时间】:2015-12-17 13:34:40
【问题描述】:

我目前正在学习 C++ 课程,并且正在努力解决参考问题。我知道有一些类似的主题,但我找不到答案。 问题是我的教授希望我们在返回对象时使用引用,所以按值返回或使用指针作为返回是没有选择的。 所以我想我必须使用动态分配的对象(返回对本地对象的引用以一团糟......对吗?)

1. Complex& method() {
2. Complex *object = new Complex();
3. return *object; }

这是我苦苦挣扎的地方,我该如何正确地抓住回报?

1. Complex one = object.method();

据我了解,这样我只会得到一个副本和一个内存泄漏 那么如何用指针捕捉呢?

1. Complex *two = new Complex();
2. delete two;
3. *two = object.method(); 

这似乎可行,但有没有办法只用一行?还是应该做不同的事情?

【问题讨论】:

  • 它们都不起作用。您的任何一个示例都在调用未定义的行为。
  • 您会将其存储在参考中吗? Complex &two = object.method();,然后是 delete &two;。请注意,通过引用删除对象是不寻常的——通常人们使用指针。

标签: c++ return-by-reference


【解决方案1】:

我的教授希望我们在返回对象时使用引用

当我读到这篇文章时,我的第一个想法是你的教授的意思是:

void method(Complex& nonConstPassByReference) 
{
    nonConstPassByReference.data = 10;
}

int method(Complex& nonConstPassByReference) 
{
    nonConstPassByReference.data = 10;
    return (0);  // no error occurred
}

当我使用这种技术时,我现在使用

std::string method(Complex& nonConstPassByReference) 
{
    std::stringstream ss;
    nonConstPassByReference.data = 10;
    // more stuff
    if (anErrorOccurred) 
       ss << errorDescriptionInfo << std::endl;
    return (ss.str());  // no error occurred when return size is 0
}

这源于一个想法,一般来说,所有方法或函数都可以有两种形式参数。我们称它们为按值传递和按引用传递。

一般来说,所有函数/方法都可以有输入和输出形式参数。通常,输入参数是按值传递的。输出参数是非 const-pass-by-reference,邀请方法体将其结果发送回调用代码的预构建实例。

有时,传递引用变量用于“输入到方法”参数(可能是为了提高性能 - 以避免昂贵的副本)。在这种情况下,input-to-method-pass-by-reference 参数应标有“const”,以便在代码尝试修改该输入时要求编译器生成错误。

请注意,许多 C 函数不会返回作为操作一部分的值...返回是“发生错误”指示,错误描述隐藏在 errno 中。

【讨论】:

    【解决方案2】:

    在返回类成员时返回引用是有效的,

    喜欢:

    class A{
      Complex member;
    public:
      Complex& method(){
        return member;
      }
    };
    

    你也可以通过返回引用的方式返回一些不能为NULL的静态或全局对象,例如:

    Complex& method() {
         static Complex c; // c cant be null
         return c;
    }
    

    使用引用的好处是你可以把函数调用当作一个对象来使用,比如:cin&gt;&gt;method().real&gt;&gt;method().img;,即使你多次调用这个方法,也可以使用同一个对象。 但是您的代码不适合使用引用,因为每次调用都会创建一个新实例。

    如果你使用动态分配,你应该返回一个指针:

    Complex* method() {
       return new Complex();
    }
    

    你应该记得删除它。

    【讨论】:

      【解决方案3】:

      一个想法是将返回的对象存储在您的对象中:

      class Obj {
      public:
        Complex &method() { c.data = 10; return c; }
      private:
        Complex c;
      };
      

      这样就没有局部变量的返回,也没有堆分配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-28
        • 2018-09-16
        • 1970-01-01
        • 1970-01-01
        • 2016-07-29
        • 1970-01-01
        • 2012-08-11
        • 1970-01-01
        相关资源
        最近更新 更多