8


3

クラスを操作する関数はメンバ関数であるべきであるというあなたの規則は何ですか対 非メンバー関数? たとえば、ブールの行列を使用して迷路を表すクラスがあります。 迷路内の2点が同じ領域内にあることを確認するisConnectedという関数を作成しています。 AからBに移動することは可能です。

これは会員か非会員か? 良い規則は何ですか?

6 Answer


14


Herb Sutterは、「合理的に可能であれば、私たちは彼らを非友好的なメンバーにしないようにしたい」と言っており、彼は私より賢いです。


13


まあ、両方のための議論があります。

非メンバー関数を支持して:

  • それはhttp://www.ddj.com/cpp/184401197をご覧ください。

  • コードの再利用が可能になります(std :: findは_any_に再利用できます) コンテナタイプ。これは無料の機能だからです。 それがメンバーであったなら、コンテナーはそれ自身を定義しなければならないでしょう)

  • それは多くの一般的なプログラミングトリックをより簡単にします。 ( `+ container `が配列の場合、 ` container.begin()`は無効です。 そのため、コンテナを扱う一般的なコードを書くのは少し面倒です。 しかし、 ` begin(container)+`は、配列のような組み込み型であっても、任意の型に対して有効にすることができます)。 それはまた、あなたが操作したいミックスインオブジェクトに到達するためにメンバーを通して自分自身を「ドット」にすることをユーザーに要求しないので、コンポジションを通してミックスインをずっときれいにすることができます。

物事をメンバ関数にすることを支持するのは、

  • おなじみです。 JavaおよびC#_require_これ、および多くの プログラマの目では、メンバー関数はOOPと同義です。

そして…​ それでおしまい。 (しかしその議論は過小評価されるべきではない。 コードの読みやすさは重要で、メンバーバージョンを読みやすくするのであれば、それが有利な主張です。 それだけでは良いコードは生成されません。 厳密な "より良いコード"の観点から、可能であれば非メンバーが優先されるべきです。


11


いつメンバー関数にするか

  • 関数がクラスと論理的に結合している場合(迷路の接続性の例のように)

  • 関数がプライベートまたは保護されたメンバーにアクセスする必要があるときは、それを友人よりもメンバーにする方が良いです。

いつそれをスタンドアロン関数にするか

  • 他のクラスで自然に動作するようにテンプレート化できる一般的な関数の場合(良い例はヘッダーを見てください)


4


この場合、私はメンバー関数に行きます。 私が従う規則は、関数がインスタンスの現在の状態の内部にある何かにアクセスしなければならないならば、それはクラスの「領域」の一部であるべきであるということです。 この場合、AとBの接続性は、オブジェクトインスタンスの状態によって異なります。

もちろん、あなたはあまりにも多くの責任を持つクラスを持つことになる可能性があります。 この場合、キープ・イット・シンプル・ファクタが効力を発揮しますので、あなたのクラスがやり過ぎようとしているかどうかを検討するべきです。 その場合、Mazeインスタンスをトラバースしてそれを処理することができるアルゴリズムを保持することが特定の役割である、分離したクラス(あなたの場合はConnectednessEvaluatorなど)を用意すると便利です。


3


私はいつもhttp://www.parashift.com/c -faq-lite / operator-overloading.html#faq-13.9 [よくある質問13.9]を参照してください。 それは正確な科学ではなく、裁量に基づくものです。

内部クラスへのアクセスが必要なときはいつでも、メンバーを使用する必要があると言っても過言ではありません。 注目すべき例は、ストリームの挿入/抽出演算子(それぞれ + >> +`と `+ << +)とバイナリの `+`です。

あなたの例では、 `+ isConnected +`はオブジェクトの状態をテストするメソッドです。 検査官であり、会員であるための理想的な候補です。


0


私が非メンバー関数を作る傾向がある唯一のものは、メンバー関数の中からのみ呼び出されるものであり(クラスの外から見える必要はありません)、そしてクラスのパブリックメンバーや小さなクラスでうまく動作できるだけですパラメータ数