web-dev-qa-db-ja.com

ポインターを間接参照すると、そのコピーが作成されますか?

ポインターを逆参照し、それを参照によって引数を取る関数に渡すと、オブジェクトのコピーが作成されますか?

37
wrongusername

この場合、ポインターの値がコピーされます(ただし、オプティマイザーが最適化する可能性があるため、必ずしもそうとは限りません)。

int val = *pPtr;

ただし、この場合、コピーは行われません。

int& rVal = *pPtr;

コピーが行われない理由は、参照がマシンコードレベルの構成ではないためです。これは高レベルの構成であるため、コンパイラーが特定のコードを生成するのではなく、内部で使用するものです。

明らかに、同じことが関数パラメーターにも当てはまります。

33
Goz

単純なケースでは、いいえ。ただし、もっと複雑なケースがあります。

void foo(float const& arg);
int * p = new int(7);
foo(*p);

ここでは、逆参照されたポインターの型(int)が関数パラメーターの基本型(float)と一致しないため、一時オブジェクトが作成されます。変換シーケンスが存在し、変換された一時オブジェクトはconst参照であるため、argにバインドできます。

7
MSalters

うまくいけば、そうではありません:呼び出された関数がその引数を値で取る場合はそうなります。

さらに、それは参照の予想される動作です:

void inc(int &i) { ++i; }

int main()
{
    int i = 0;
    int *j = &i;
    inc(*j);
    std::cout << i << std::endl;
}

このコードは1becauseincを出力することが期待されています。 inc呼び出し時にコピーが作成された場合、コードは0を出力します。

4
icecrime

いいえ。参照は、多かれ少なかれ、異なる表記法とnull参照がないという制限のあるポインターのようなものです。しかし、ポインタのように、オブジェクトのアドレスだけが含まれています。

3
hmuelner