2012-02-27 13 views
2

オブジェクト指向プログラミングでは、別のクラスのメソッドでクラスのインスタンスに何とかアクセスする必要があるときに、そのインスタンスを引数に渡すことに変わりはありません。オブジェクトを渡すか参照/ポインタを渡すか?

私は好奇心が強いですが、オブジェクトやオブジェクトへのポインタのいずれかを渡す際に、良い練習の点で違いはありますか?

+2

2人は違うことをしていますので、どちらが望ましいかを尋ねることはできません。あなたの問題を解決するものを使用してください。 –

+0

あなたの質問は次のようなものです:私は旅行したいです。電車や飛行機で行かなければならない。まあ、どこへ行くの?あなたは何をしようとしているのですか? – Adrian

答えて

8

オブジェクトを参照渡しする習慣を身に付けましょう。

void DoStuff(const vector<int>& values) 

あなたは、元のオブジェクトを変更する必要がある場合

は、 const修飾子を省略します。

void DoStuff(vector<int>& values) 

空/無回答を受け入れる場合は、ポインタで渡します。

void DoStuff(vector<int>* values) 

ローカルコピーに追加する場合は、値渡しします。

void DoStuff(vector<int> values) 

問題は、大量の並行性を導入すると実際にポップアップするだけです。その時までに、特定の合格技法を使用しない時期を十分に知ることができます。

+2

まだ完全な答えがありますか?その値渡しは、コピーコンストラクタ(およびシグネチャの例)を使用します。 – Kru

+0

偉大な答え。どうもありがとう。 :D – Lemmons

+0

+1生のポインタを使用するのではなく、 'boost :: optional'を推奨するために、スーパークリアであるために – vulkanino

0

実際には、オブジェクトが存在しないことを何とか示したい場合を除き、実際にはオブジェクトへのポインタを渡す正当な理由はありません。

オブジェクトを変更する場合は、そのオブジェクトに参照を渡します。関数内での変更からそれを保護したい場合は、値または少なくともconst参照で渡します。

速度向上のために参考にして渡される人もいますが(たとえば、構造自体ではなく大きな構造のアドレスのみを渡します)、私はそれに同意しません。ほとんどの場合、私は自分のソフトウェアが速いよりも安全であることを望んでいます。「よりも最適化されたものは得られません。 :-)

+0

これは定数参照として渡すのが一般的な理由です。あなたは安全で速いです! :D – TheBuzzSaw

+0

良い点、私はそれを追加します。 – paxdiablo

0

実際、メソッドに渡すことができるのは、オブジェクトへのポインタ、オブジェクトへの参照、およびオブジェクトのコピーであり、これらはすべて定数でもあります。ニーズに応じて、ニーズに最も適したものを選択する必要があります。

最初に行うことができるのは、渡すものがあなたの方法で変更できるかどうかです。あなたがそれを変更しようとしないなら、おそらく最良の代替案ではconst参照を(私はあなたがそのオブジェクトの非constメソッドを呼び出すつもりはないということも意味しています。そのメリットは何ですか?あなたはオブジェクトをコンパイルするための安全な時間を得ることができ、メソッドシグネチャ自体も "私はそのパラメータを変更しません"と言います。

このオブジェクトを変更する必要がある場合は、参照またはポインタを渡すことができます。これらのオプションのうちの1つだけを選択することは、必ずしも必須ではありません。私が考えることができる唯一の違いは、参照が常に存在するオブジェクトを指している間、ポインタがNULL(つまり、オブジェクトをまったく指していない)である可能性があるということです。

メソッドで必要なものがオブジェクトのコピーである場合、オブジェクトのコピー(参照ではなくポインタではないもの)を渡す必要があるもの。あなたの方法は

void Foo(const A& a) { 
    A temp = a; 
} 

のように見える場合たとえば、その後、そのコピーを渡すと、より良い代替手段であることを明らかに示しています。

これは物事を少しはっきりさせることを望みます。

1

constをデフォルトとして選択します。もちろん、非const場合は、クライアントのオブジェクトを変更する必要があります。参照を使用することからの偏差はめったに必要ありません。

参考文献があるので、ポインタはC++のようなものではありません。参照は何も参照することが禁じられているので、いいです。 更新:明確にするには、型と配列用の適切なコンテナが望ましいですが、内部実装によってはポインタを渡す必要があります。

オブジェクト/値は、セマンティクスではまったく異なります。私はコピーが必要な場合は、私は一般的にちょうど必要な関数の中に作成されます:あなたは(NULLを渡すことで)存在しないことを示すことができるようにしたい場合は

void method(const std::string& str) { 
    std::string myCopy(str); 
    ... 
+1

私は何とかC++のプラクティスにとって有害なポインタには同意しませんが、私は定数参照を渡すことに同意します。維持するのが最善の習慣です。 – TheBuzzSaw

+2

@Justinとにかくコピーを作成しようとするなら、値渡しにはいかがですか?たとえば、http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ – juanchopanza

+0

@TheBuzzSawを参照してください。ポインタと配列について:私はコンテナ型を使用します。 「オプションのパラメータ」について:私は2つの一般に見える呼び出しを提供する傾向があります。これらの呼び出しは、オプションのパラメータを使用するプライベート実装を呼び出すことがあります。ポインタパラメータが一般的に「本当に内部的な」実装の詳細のために予約されている場合、多くの安全性が追加され、読みやすさが向上します(私が見つける)。しかし、もちろん、他の好みを持っている人もいます。 – justin

1

は、オブジェクトへのポインタを渡します。

オブジェクトの値渡しをしないでください。呼び出しコンストラクタを呼び出して、呼び出し関数のスコープ内でオブジェクトのローカルバージョンを作成するためです。代わりに、参照渡し。ただし、ここには2つのモードがあります。オーバーヘッドなしで値(不変の "コピー")を渡すこととまったく同じ効果的な振舞いを得るためには、const参照を渡します。渡されたオブジェクトを変更する必要があると感じたら、(非const)参照を渡します。

0

オブジェクト指向プログラミングは、多形性、リスコフ置換原理、新しいコードを呼び出す古いコードについてです。名前を付けます。コンクリート(派生)オブジェクトを、より抽象的な(基本)オブジェクトで動作するルーチンに渡します。あなたがそれをしていないなら、あなたはOOPをやっていません。

これは、参照またはポインタを渡すときにのみ達成できます。値渡しは、um値に最適です。

値とオブジェクトを区別すると便利です。値は常に具体的ですが、多型はありません。彼らはしばしば不変です。 5は5であり、「abc」は「abc」である。値をまたは(const)の参照で渡すことができます。

オブジェクトは常にある程度抽象です。オブジェクトを与えられると、ほとんどの場合、それをより具体的なオブジェクトに絞り込むことができます。 RectangularAreaはDrawableである可能性があります。これは、ManagedWindowである可能性のあるToplevelWindowになる可能性のあるウィンドウになる可能性があります。を参照渡しする必要があります。

ポインターは完全に別々のワームです。私の経験では、裸のポインタは避けるのが最善です。スマートポインタは、NULLにすることはできません。オプションの引数が必要な場合は、boost::optionalなどの明示的なoptionalクラステンプレートを使用します。

+0

+1。 – Andre

+0

どのスマートポインタ "NULLにすることはできません"をお勧めします。私が知る限り、すべてのスマートポインタは空にすることができます。 – Andre

+0

@Andre:私は自分で作る。 –

関連する問題