2010-12-13 9 views
23

ポインタ引数を渡していますが、C++で値渡ししていますか?ポインタの変更はメソッドの外部には反映されていないことがわかります。ポインタを逆参照することによって私が行う変更は反映されます。ポインタの引数を渡していますが、C++で値渡ししていますか?

その場合、関数の引数としてポインタへのポインタを使用して、関数内でポインタの値を変更することは可能ですか?

+5

ポインタは値によって渡されますが、ポインタによって指示されたオブジェクトは関数(const-qualification依存)によって変更できます。 – dreamlax

答えて

24

両方に該当します。

ポインタは他のものとして値渡しされます。つまり、ポインタ変数の内容(指し示されているオブジェクトのアドレス)がコピーされます。つまり、関数本体のポインタの値を変更すると、その変更は古いオブジェクトを指し示す外部ポインタに反映されません。しかし、あなたが指しているオブジェクトの値を変更することができます。

ポインタに加えられた変更を外部ポインタに反映させたい場合は、2つのレベルの間接指定(ポインタへのポインタ)が必要です。関数を呼び出すときには、ポインタの前に&を置くことで終了します。これは、標準的なCのやり方です。

C++を使用する場合、参照を使用する方がポインタよりも優先されます(これはポインタへのポインタにもなります)。 なぜ参照の場合

がポインタに優先しなければならない、いくつかの理由があります:

  • 参照は、関数本体内のポインタよりも少ないsyntaxic雑音を導入
  • 参照が可能よりも、ポインタよりも多くの情報を保ちますコンパイラ

参照の欠点のために有用なのは、主に以下のとおりです。

  • Cの値渡しの単純なルールを破って、パラメータに関する関数の動作を理解しやすくします(変更されますか?)。また、関数プロトタイプが必要です。しかし、それは実際にCを使用するときに必要な複数のポインタレベルより悪くはありません。
  • Cでサポートされていません.CとC++プログラムの両方で動作するはずのコードを書くときに問題があります通常の場合)。

ポインタの特定のケースでは、その違いはほとんど単純ですが、参照を使用するとポインタの両方のレベルを削除してポインタへのポインタではなく参照を1つだけ渡すのも簡単です。

+1

参照用のポインタを使用するのはなぜ好ましいですか? – Arafangion

+0

@Arafangion:私の答えを編集して、なぜプリファレンスが優先されるべきかを説明しました。 – kriss

+0

私はそれが主観的だと思う - 私は呼び出し側にヌルポインターチェックの責任を移すので、私は参照を使用することを好む、私は通常Cの互換性については気にしない。しかし、私は "値が変更されていないことを確かめるために関数プロトタイプが必要です"ということは確かではありません - それはC++の多くのクラスに当てはまります - それはポインタであり、データを共有するかもしれないし、つまり、私は値渡しを優先し、必要に応じてクラスがポインタを必要としているかどうかを問わず、直ちに設定する必要がある値の参照を返さない限り、+1 – Arafangion

0

ポインターへのポインターまたはポインターへの参照は、ポインター自体を変更する可能性がある場合に使用します。あなたの元の質問には、技術的には、すべてのパラメータが値渡しされます。

+7

"すべてのパラメータは値によって渡されます"いいえ、参照渡しの引数は値渡されません。 –

0

はいそれはその場合、C.

にあるように、関数内のようなポインタ値を変更する関数の引数としてポインタへのポインタを使用することが許容される/標準的な手順であります?

この場合、なんでしょう?&修飾子付きの実数参照を使用できます。

void func(type &ref); 
6

私はここで混乱を理解しています。たとえそれがそうであっても、「値渡し」と「参照渡し」という概念はあまり明確ではありません。 コンピュータはこれらの概念を知らず、それに従って動作しないことに注意してください。 コンピュータは種類について認識していません。したがって、ポインタと値の区別はしません。 私はによってと例を説明してみましょう:

void func1(int x) 
{ 
    x = 5; 
} 

void func2(int *x) 
{ 
    int a; 
    x = &a; 
} 

操作は、両方の機能で、マシンのための同じである:それは、引数を取得し、それを変更します。 2番目の関数では、modifiy * xではなく、xを変更しています。我々は

int y = 10; 

func1(y); //value of y does not change 

func2(&y); //value of &y does not change, but the value of the address which y points may change. 

、これらの関数を呼び出す場合

は、今私はは基本的に、すべての関数呼び出しは、「値によってコール」である、と言うことを好みます。しかし、ポインタ型の場合、メモリ内の別のアドレスの内容を変更する方法があります。

我々は

void func2(int *x) 
{ 
    *x = 5; 
} 

としてfunc2を書いていた場合はその後、これは「参照による呼び出し」の実際のケースになります。

関連する問題