C ++引用和返回值

时间:2016-04-28 15:28:15

标签: c++ reference

我遇到了以下代码:

class MyClass {

// various stuff including ...
   double *myarray;

   double &operator() (const int n){
      return myarray[n];
   }
   double operator() (const int n) const {
      return myarray[n];
   }

// various other stuff ...
}

那么"()"的那两个重载的实际区别是什么?我的意思是,我知道"第一个返回对double的引用,第二个返回一个double,"但这实际意味着什么呢?我什么时候使用那个?我何时会使用另一个?第二个(返回一个)似乎非常安全和直截了当。第一个在某种程度上是危险的吗?

4 个答案:

答案 0 :(得分:6)

它们的不同之处在于,第一个允许您修改数组元素,而第二个只返回值,因此您可以:

with: double& operator()

MyClass mm;
mm(1) = 12;

但也是:

std::cout << mm(1);

with: double operator()

// mm(1) = 12; // this does not compile
std::cout << mm(1); // this is ok

另外,使用operator[]时返回引用更为常见,就像使用std::vector::operator[]时一样。

顺便说一句。它的共同点是operator()的两个版本 - 一个const和第二个非const。 const版本将在const对象上调用,而第二个在非const上调用。但通常他们的签名是:

double& operator() (const int n);
const double& operator() (const int n) const;

答案 1 :(得分:4)

通常,指针和引用之间的区别在于指针可以更改,也可以指向double,即无指向。参考文献是固定的。

但是,在此示例中,operator()不返回引用,而是返回值的副本,即更改以该方式检索的值不会更改类中的//Dont use pixels use % different screens have different needs. .DSLBlurb a { color: white; top: 10%; left: 16%; }

如果它真的返回了一个双&amp;,那么你可以互换使用这两种方法(当然在使用中使用不同的符号),并且提供这两种方法对于这个类的用户来说只是一个受欢迎的方便。

答案 2 :(得分:4)

  

这实际意味着什么?

这意味着第二个方法返回by-value,即它生成array-item / double的副本并将该副本返回给调用者。第一种方法返回by-reference,即它不会复制double,而是返回对原始/ in-the-array double位置的引用,调用代码可以使用该位置如果想要,直接访问in-the-array double。 (如果有帮助,返回引用的间接语义有点像指针语义,除了语法更类似于传统的C / C ++按值功能)

  

我什么时候使用这个?我什么时候会使用另一个?

按值方法更安全,因为调用未定义行为的可能性较小; by-reference方法为您提供了更多的灵活性(即调用者可以通过写入他作为返回值接收的引用来更新数组中的项目)并且在某些情况下它可能更有效(例如,返回引用可以避免需要复制对象,如果对象很大或很复杂,这可能是一个昂贵的操作)。对于像double这样的小对象,返回的by-value可能比返回by-reference更有效。

  

[参考方法]在某种程度上是否有危险?

它可以是 - 例如,如果你要返回对自动/堆栈变量的引用,那将导致未定义的行为,因为变量将在调用代码可以使用之前被销毁:

double & dont_ever_do_this()
{
    double x = 5.0;  // x will be destroyed as this method returns!
    return x;        // so returning a reference to x is a silly thing to do
}

类似地,在MyClass示例中,如果调用者保留返回的引用,然后在删除myarray之后尝试使用它,则调用者将读取(或写入)不再有效的内存位置,这将导致未定义的行为(读:坏事)发生。

当然,返回非const引用意味着调用者能够更改返回的数组项的内容,而不会让您的类知道它,这可能不是您想要允许的。

答案 3 :(得分:2)

您可以通过此链接查看价值类别。 http://en.cppreference.com/w/cpp/language/value_category

double& operator()情况下你有左值表达式并且可以使用像左值(用于赋值,打印等)

MyClass class;
class(7) = 21;

std::cout << class(7);

double operator() const案例中你有rvalue表达式。 在这种情况下,您还可以将其与const对象一起使用。