什么是参考回报的意义?

时间:2010-07-09 10:00:53

标签: c++

在C ++中,

function() = 10;
如果函数通过引用返回变量,则

起作用。

有什么用例?

11 个答案:

答案 0 :(得分:20)

最常见的情况是实现operator []。

之类的东西
struct A {
    int data[10];
    int & operator[]( int i ) {
         return data[i];
    }
};

另一种方法是通过访问函数从类中返回一个大对象:

struct b {
    SomeBigThing big;
    const SomeBigThing & MyBig() const {
         return big;
    }
};

以避免复制开销。

答案 1 :(得分:7)

考虑以下代码,MyFunction返回一个指向int的指针,并将值设置为int。

int  *i;
i = MyFunction();
*i = 10;

现在将其缩短为

*(MyFunction()) = 10;

它与第一个代码块完全相同。

您可以将引用视为一个始终取消引用的指针。因此,如果我的函数返回一个引用 - 而不是一个指针 - 到一个int,frist代码块将成为

int  &i;
i = MyFunction();
i = 10;

,第二个将成为

MyFunction() = 10;

这就是我要找的东西

答案 2 :(得分:4)

Getters / setters例如

class C
{
    int some_param_;
public:
    int& param() { return some_param_; }
    int const& param() const { return some_param_; }
};

但是你应该将some_param作为公共int。容器提供通过引用返回的功能,例如。 vector<T>::operator[]以便您可以撰写v[k] = x

答案 3 :(得分:3)

一个非常正常的用例是当你编写类这样的数组时。在这里,您要重载operator [],以便{J} a[0] = 10;在这种情况下,您希望签名与int& operator[](int index);一样

答案 4 :(得分:2)

如果您有一个包含其他结构的类,直接修改包含的结构可能很有用:

struct S
{
    int value;
};

class C
{
    public:

        S& ref() { return m_s; }

    private:

        S m_s;
};

允许您编写如下内容:

void foo()
{
    C c;

    // Now you can do that:

    c.ref().value = 1;
}

注意:在此示例中,直接将m_s公开,而不是返回引用可能更为直接。

答案 5 :(得分:2)

搞砸了我的回答

您甚至不需要返回引用:

struct C { };

C f() {
  return C();
}

int main() {
  C a;
  f() = a;  // compiles fine
}

因为这种行为非常令人惊讶,所以通常应该返回一个const值或一个const引用,除非用户有明智的意图来修改结果。

答案 6 :(得分:2)

在实施评估员时非常有用

class Matrix
{
   public:
      //I skip constructor, destructor etc

      int & operator ()(int row, int col)
      {
         return m_arr[row + col * size];
      }

   private:
      int size;
      int * m_arr;
}

Matrix m(10);
m(1,0) = 10;  //assign a value to row 1, col 0

答案 7 :(得分:1)

另一个经典案例:

class Foo {
  Foo();
public:
  static Foo& getSingleton();
};

答案 8 :(得分:0)

std::vectoroperator[],否则不允许vec[n] = m

答案 9 :(得分:0)

您还可以使用按引用返回来实现方法链(如果您愿意)。

class A
{
public:
    A& method1()
    {
        //do something
        return *this;   //return ref to the current object
    }
    A& method2(int i);
    A& method3(float f);  //other bodies omitted for brevity
};

int main()
{
    A aObj;
    aObj.method1().method2(5).method3(0.75);

    //or use it like this, if you prefer
    aObj.method1()
        .method2(5)
        .method3(0.75);
}

答案 10 :(得分:0)

named parameter idiom是另一个用例。考虑

class Foo
{
public:
    Foo(
        int lions,
        float tigers,
        double bears,
        std::string zookeeper
    );
};

此类用户需要记住每个参数的位置

Foo foo( 1, 2.0, 5, "Fred" );

在不查看标题的情况下可以是不明显的。与像这样的创作者类相比

class CreateFoo
{
friend class Foo;
public:
    CreateFoo();

    CreateFoo& lions(int lions) {
        _lions = lions;
         return *this;
    }

    CreateFoo& tigers(float tigers) {
        _tigers = tigers;
        return *this;
    }

    CreateFoo& bears(double bears) {
        _bears = bears;
        return *this;
    }

    CreateFoo& zookeeper(const std::string& zookeeper) {
        _zookeeper = zookeeper;
        return *this;
    }

private:
    int _lions;
    float _tigers;
    double _bears;
    std::string _zookeeper;
};

然后可以由客户使用

Foo foo = CreateFoo().
    lions(1).
    tigers(2.0).
    zookeeper("Fred").
    bears(5)
    ;

假设Foo的构造函数采用const CreateFoo&