yoppa.org


Blog

C++の疑問: 値渡し、参照渡し、ポインタ渡し

※ 末尾に追記あり。

C++、いろいろ未だにわからにことだらけなのだけれど、関数に値を送る場合の

  • 値渡し
  • 参照渡し
  • ポインタ渡し

の違いがいまだにすっきりと整理できていない。

C++、自分の場合はoFで使うことがほとんどなので、oFのコードで実験してすっきりしてみようとシンプルなコードを書いてみた。

力をベクトルで与えると運動するParticleというクラスを以前から作っていたいので、これはそのまま流用。長くなるのでコードの内容は割愛。

Particleを操作するためのMoverというクラスをつくってみた。このMoverクラスは3種類の方法でParticleのインスタンスを受けとることができる

  • A: 値渡し
  • B: 参照渡し
  • C: ポインタ渡し

Mover.h

Mover.cpp

これを、ofAppから呼びだしてみる。

ofApp.cpp

実行結果はどうなったかというと

  • A: 値渡し → 動かない
  • B: 参照渡し → 動かない
  • C: ポインタ渡し → 動いた

Aの値渡しが動かないのは、まあ予想内の挙動。そして、Cのポインタ渡しでは狙い通りofAppのParticleのインスタンスもMoverから更新され、無事動いた。

解せないのは、Bの参照渡しの挙動。参照渡しはオブジェクトの実体ではなく、あくまでその参照として渡っているので、ofApp側のインスタンスも連動して更新されると考えていたのだが、このコードではそうならなかった。うーん、何故なんでしょう。

C++はムズカシイネ…

プロジェクト全体は下記にあります。

【追記】: Facebookでコメントしていただき、参照渡しがうまくいかなかった原因判明。Mover.cppの11行目で、”particleB = p;”と代入している。ここでpをparticleBにコピーしてしまっていて、その結果参照から外れてしまったということのようだ。うーん、なるほど。参照渡しはクラスのメンバとして扱うのは難しいですね…

こう修正したら、参照渡しでも動きました。クラス変数を参照渡しするには、コンストラクタの初期値として渡す必要あるみたい。ううむ、扱い難しいですね。

Mover.h

Mover.cpp

ofApp.cpp

  • フォルノ

    数年も前の投稿にコメするのはいかがなものかと思いましたが、
    追記に書かれている particleB = p; の問題点はparticleBが参照ではなく実体なことなので
    particleBの宣言を Particle &particleB; にするだけで初めのコードを変えることなく動くと思いますよ。