3

コードがあるとします

#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 修飾子と共に渡されるためです。ただし、x に対して f を呼び出すことにより、g() 内で y の値を変更できます。

ポインターを使用すると、非常によく似たものが得られます

struct B{
  int* x;  
}

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

許可されています。これは完全に明らかです。非 const int への const ポインターがあります。しかし、前の参照の例では、参照がオブジェクトである場合、なぜこの場合はポインターとして動作するのでしょうか? この動作の下での設計ポリシーは何ですか?

4

3 に答える 3

4

参照がオブジェクトの場合

ただし、参照はオブジェクトではありません。オブジェクトへの参照です。

参照自体を const にすることはあまり役に立たないというのはあなたの言うとおりです。それらは再挿入できないため、いずれの場合もポインターのように変更することはできません。

実際、参照を特殊な構文を持つ const ポインター (const へのポインターではなく!) と考える方が役立つ場合があります。

レフェリーからレフェラントに constness を伝播する間接化が必要な場合(つまり、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 のメンバー (ポインターまたは参照) にどのように適用され、指示対象に伝搬されないかに注意してください。
于 2012-07-31T12:21:27.917 に答える
3

標準の実際の言語は

8.3.2 参照 [dcl.ref]

1 - [...] [ 注: 参照は、オブジェクトの名前と考えることができます。—終わりのメモ]

したがって、参照がオブジェクト自体ではなくオブジェクトの名前constである場合、囲んでいる構造体を名前にすることは理にかなっていますconstが (参照は再バインドできないため、意味がありません)、オブジェクト自体ではありません。

私たちも見ます

6 - typedef、型テンプレート パラメータ、または decltype-指定子が型 T への参照である型 TR を示す場合、型「cv TRへの左辺値参照」を作成しようとすると、「左辺値参照への左辺値参照」が作成されます。 T」 [...]

cvオブジェクトに対するメンバー アクセスはcv左辺値を作成するため、同じことが適用され、cv修飾は消滅します。

于 2012-07-31T12:21:50.560 に答える
0

C++ では、通常、参照はポインターによって実装されます。sizeof(参照とポインタは同じだと思います)。

実際、私は通常参照をポインターと考えていますが、構文は異なります。

于 2012-07-31T12:19:00.643 に答える