9

私はC++での参照の概念を理解しており、関数パラメーターで使用されたときにそれらが何をするかを理解していますが、それらが戻り型でどのように機能するかについてはまだ非常に混乱しています。

たとえば、パラメータで使用する場合、次のコードを使用します。

int main (void) {
  int foo = 42;
  doit(foo);
}

void doit (int& value) {
  value = 24;
}

このコードに似ています:

int main (void) {
  int foo = 42;
  doit(&foo);
}

void doit (int* value) {
  *value = 24;
}

(コンパイラーは、 doitの最初のコードサンプルで使用されるたびに値の前にアスタリスクを自動的に配置しますが、後者では、を使用しようとするたびに自分自身にアスタリスクを配置する必要があります)

では、参照として使用する場合、この次のコード(戻り型で参照を使用)は何に変換されますか?intへのポインタを返しますか?それとも、intを返すだけですか?

int main (void) {
  int* foo = /*insert useful place in memory*/;
  foo = doit(foo);
}

int& doit (int* value) {
  //insert useful code
}
4

4 に答える 4

24

これは、参照によって戻ることを意味しますが、少なくともこの場合は、おそらく望ましくありません。これは基本的に、戻り値が関数から返されたもののエイリアスであることを意味します。それが永続的なオブジェクトでない限り、それは違法です。

例えば:

int& foo () {
    static int x = 0;
    return x;
}

//...
int main()
{
    foo() = 2;
    cout << foo();
}

によって返される実際の値を変更する2ため、合法で印刷されます。foo() = 2foo

でも:

int& doit () {
    int x = 0;
    return x;
}

メソッドが終了すると破棄されるため、不正になります(戻り値にアクセスすると)、xぶら下がっている参照が残ります。

参照による戻りは、free関数では一般的ではありませんが、メンバーを返すメソッドでは一般的です。たとえば、のではstdoperator []forcommonコンテナは参照によって返されます。たとえば、でベクトルの要素にアクセスすると、[i]その要素への実際の参照が返されるため、v[i] = x実際にその要素を変更します。

また、「本質的にこのコードと等しい」とは、意味的には(実際にはではないが)類似していることを意味することを願っています。これ以上何もない。

于 2012-12-05T07:47:44.587 に答える
4

これは、データそのものではなく、対応するデータがあるメモリアドレスへのポインタを返すことを意味します。

于 2012-12-05T20:40:43.163 に答える
1

このコードを想定すると(最初の例と比較できるようにするため):

int main (void) {
  int* foo = /*insert useful place in memory*/;
  *foo = doit(foo);
}

int& doit (int* value) {
  *value = 24;
  return *value;
}

これint&は、メモリ内の変数(関数へのポインタを渡す)へのアクセスを提供するため、この場合の戻り型としてはあまり役立ちません。

intへのポインタを返しますか?それとも、intを返すだけですか?

いいえ、intへの参照を返します。必要に応じて、それをポインタとして見ることができますnullptr

于 2012-12-05T08:02:35.230 に答える
0

うーん、答えを知る最良の方法は試してみることです...

戻り値をintのポインターとして受け入れる間、doitはintの参照を返すため、コードは型チェックに合格しません。

あなたはこれを見ることができます:

#include<iostream>
using namespace std;
int& doit (int* value) {
    value[0] = 3;
    return value[4];
}
int main (void) {
  int* foo = new int[10];
  for (int i=0; i<10; i++)
    foo[i] = i;
  int& bar = doit(foo);
  cout<<bar<<endl;
  for (int i=0; i<10; i++)
      cout<<foo[i]<<" ";
  cout<<endl;
  bar = 12;
  for (int i=0; i<10; i++)
      cout<<foo[i]<<" ";
  cout<<endl;
  return 0;
}

変数「bar」は戻り値を受け入れ、「foo」の内容を変更するために使用できます。Luchianが述べているように、後のコードがスタック内の値を変更する可能性があるため、関数から参照を返すのは危険な場合があります。

于 2012-12-05T07:58:10.500 に答える