设计原因引用了const引用传递的类的引用成员

时间:2012-07-31 12:10:55

标签: c++ reference

假设有代码

#include <iostream>

struct A{
  int y;
  int& x;
  A():y(0),x(y){}
};



void f(int& x){
  x++;
}

void g(const A& a){
  f(a.x);
  //f(a.y);
}


int main(){
  A a;
  g(a);
  std::cout<<a.y<<std::endl;

}

在g()内 不允许在y上调用f(),因为a与const修饰符一起传递 但是,y的值可以通过调用x on x;

在g()中修改

使用指针,类似的东西可以非常相似地获得

struct B{
  int* x;  
}

g(const B&){
   *x++;
}

是允许的。这非常清楚:我们有一个指向非const int的const指针。 但是在前面的参考示例中,如果引用是对象,为什么在这种情况下它们表现为指针?这种行为有哪些设计政策?

3 个答案:

答案 0 :(得分:4)

  

如果引用是对象

引用是不是对象 - 它们是对象的引用。

你是对的,自己制作一个引用const并不是很有用:因为它们是不可重载的,所以在任何情况下它们都不能像指针那样被变异。

事实上,将引用视为具有特殊语法的const指针(不是指向const的指针!)可能更有帮助。

请注意,如果您想要一个间接,它确实从裁判传播到指示对象(即,防止f(a.x)调用此处),您可以编写一个智能指针式做的事情。


具体例子

struct A
{
    int x;
    int *p;
    int &r;

    A() : x(0), p(&x), r(x) {}
};

现在在A a

  • a.x是一个可变的int
  • a.p是一个可变指针(所以我们可以重新设置它)到一个可变的int(我们可以改变它指向的整数的值)
  • a.r是对可变int的引用
    • 请注意,因为我们无论如何都不能改变(重置)引用,它并不意味着引用本身可以是const或mutable

...但在const A b

  • b.x是一个常数
  • b.p是一个常量指针(因此我们无法重置它)到一个可变的int
  • b.r是对可变int的引用
    • 注意如何将constness应用于A的成员(指针或引用),并且传播到指示对象。

答案 1 :(得分:3)

标准中的实际语言是

  

     

8.3.2参考文献[dcl.ref]

     

1 - [...]   [注意:引用可以被认为是对象的名称。 - 后注]

因此,如果引用是对象的名称,而不是对象本身,那么使封闭结构const成为名称const是有意义的。 (这是没有意义的,因为参考不能反弹),但不是对象本身。

我们也看到了

  

6 -   如果typedef,type template-parameter或decltype-speci fi er表示类型TR   这是对类型T的引用,尝试创建类型“对 cv TR的左值引用”会创建类型“对T的左值引用”[...]

由于 cv 对象上的成员访问权限会创建 cv 左值,因此同样适用,并且 cv 资格也将被取消。

答案 2 :(得分:0)

在C ++中,引用通常由指针实现。 (我认为sizeof引用和指针是相同的。)

实际上,我通常认为引用是指针,但语法不同。