1

チーム内の C++ スタイルの違いについて誰かが教えてくれました。私はこの件に関して私自身の見解を持っていますが、皆さんからの賛否両論興味があります.

そのため、2 つのゲッター (1 つは読み取り/書き込み、もう 1 つは読み取り専用) を介して公開したいクラス プロパティがある場合 (つまり、set メソッドはありません)。少なくとも 2 つの方法があります。

class T ;

class MethodA
{
   public :
      const T & get() const ;
      T & get() ;

      // etc.
} ;

class MethodB
{
   public :
      const T & getAsConst() const ;
      T & get() ;

      // etc.
} ;

それぞれの方法の長所と短所は何でしょうか?

私は C++ の技術的/意味的な理由にもっと興味がありますが、スタイルの理由も歓迎します。

1 つの大きな技術的欠点があることに注意しMethodBてください (ヒント: 一般的なコードで)。

4

11 に答える 11

10

C++ は、ほぼすべての状況でメソッド A に完全に対応できるはずです。いつも使っていますが、困ったことはありません。

方法 B は、私の意見では、OnceAndOnlyOnce に違反するケースです。そして、最初にコンパイルするコードを記述するために、const 参照を扱っているかどうかを確認する必要があります。

これは文体的なものだと思います。技術的にはどちらも機能しますが、MethodA を使用するとコンパイラの動作が少し難しくなります。私にとって、それは良いことです。

于 2008-09-18T21:24:23.630 に答える
8

まず、「this」ポインターが const の場合に getAsConst を呼び出す必要があります。const オブジェクトを受け取りたい場合ではありません。そのため、他の問題と並んで、微妙に名前が間違っています。(「this」が非定数の場合でも呼び出すことができますが、それはここでもそこでもありません。)

それを無視すると、getAsConst は何も得られず、インターフェイスを使用する開発者に過度の負担がかかります。「get」を呼び出して必要なものを取得していることを知る代わりに、現在 const 変数を使用しているかどうか、および取得している新しいオブジェクトが const である必要があるかどうかを確認する必要があります。その後、何らかのリファクタリングによって両方のオブジェクトが非 const になった場合、呼び出しを切り替える必要があります。

于 2008-09-18T21:34:35.697 に答える
4

個人的には、より一貫したインターフェイスになるため、最初の方法を好みます。また、私には getAsConst() は getAsInt() と同じくらいばかげているように聞こえます。

別の注意として、クラスのデータメンバーへの非 const 参照または非 const ポインターを返す前に、よく考えてください。これは、理想的には非表示にする必要がある、クラスの内部動作を利用するように人々を招待するものです。つまり、カプセル化を破ります。get() const と set() を使用し、他に方法がない場合、または配列の要素への読み取り/書き込みアクセスを許可するなど、本当に意味がある場合にのみ、非 const 参照を返します。またはマトリックス。

于 2008-09-18T21:26:01.707 に答える
1

標準ライブラリによって設定されたスタイルの前例 (つまり、begin() および begin() const の例を 1 つだけ挙げる) を考えると、メソッド A が正しい選択であることは明らかです。方法Bを選ぶ人の正気を疑う。

于 2008-09-18T21:37:55.283 に答える
1

したがって、一般的には最初のスタイルが推奨されます。

const と非 const の使用法を大きく区別したいので、現在取り組んでいるコードベースでは 2 番目のスタイルのバリエーションをかなり使用しています。

私の具体的な例では、getTessellation と getMutableTessellation があります。これは、コピー オン ライト ポインターで実装されます。パフォーマンス上の理由から、可能な限り const バージョンを使用したいので、名前を短くし、別の名前にして、とにかく書き込むつもりがないときに誤ってコピーを作成しないようにします。

于 2008-09-18T23:45:00.767 に答える
0

私が見たMethodBの主な技術的欠点は、ジェネリックコードを適用するときに、constバージョンとnon-constバージョンの両方を処理するためにコードを2倍にする必要があることです。例えば:

Tが注文可能なオブジェクトであるとしましょう(つまり、演算子<を使用してタイプTのオブジェクトと比較できます)、2つのMethodA(または2つのMethodB)の間の最大値を見つけたいとしましょう。

MethodAの場合、コーディングする必要があるのは次のとおりです。

template <typename T>
T & getMax(T & p_oLeft, T & p_oRight)
{
   if(p_oLeft.get() > p_oRight.get())
   {
      return p_oLeft ;
   }
   else
   {
      return p_oRight ;
   }
}

このコードは、タイプTのconstオブジェクトとnon-constオブジェクトの両方で機能します。

// Ok
const MethodA oA_C0(), oA_C1() ;
const MethodA & oA_CResult = getMax(oA_C0, oA_C1) ;

// Ok again
MethodA oA_0(), oA_1() ;
MethodA & oA_Result = getMax(oA_0, oA_1) ;

問題は、この簡単なコードをMethodBの規則に従って何かに適用したいときに発生します。

// NOT Ok
const MethodB oB_C0(), oB_C1() ;
const MethodB & oB_CResult = getMax(oB_C0, oB_C1) ; // Won't compile

// Ok
MethodA oB_0(), oB_1() ;
MethodA & oB_Result = getMax(oB_0, oB_1) ;

MethodBがconstバージョンとnon-constバージョンの両方で機能するには、両方ともすでに定義されているgetMaxを使用する必要がありますが、それに次のバージョンのgetMaxを追加します。

template <typename T>
const T & getMax(const T & p_oLeft, const T & p_oRight)
{
   if(p_oLeft.getAsConst() > p_oRight.getAsConst())
   {
      return p_oLeft ;
   }
   else
   {
      return p_oRight ;
   }
}

結論として、const-nessの使用に関してコンパイラーを信頼しないことにより、1つで十分なはずのときに、2つのジェネリック関数を作成する必要があります。

もちろん、十分なパラノイアがあれば、2番目のテンプレート関数はgetMaxAsConstと呼ばれるはずです...したがって、問題はすべてのコードに伝播します...

:-p

于 2008-09-19T16:38:28.900 に答える
0

あなたの質問は 1 つの方法にしか対応していないように見えますが、スタイルについて意見をいただければ幸いです。個人的には、スタイル上の理由から前者の方が好きです。ほとんどの IDE は、関数の型シグネチャをポップアップ表示します。

于 2008-09-18T21:22:21.513 に答える
0

私は最初のものを好むでしょう。本質的に同じことを行う 2 つのものが同じように見えると、コード内で見栄えがよくなります。また、const 以外のオブジェクトを持っているのに const メソッドを呼び出したいということはまれです。そのため、あまりコンサーンではありません (最悪の場合、const_cast<> だけが必要になります)。

于 2008-09-18T21:25:36.840 に答える
0

const1 つ目は、コードをさらに変更することなく、変数の型を (そうであるかどうかに関係なく) 変更できるようにします。もちろん、これは、これが意図したパスから変更された可能性があることを開発者に通知しないことを意味します。つまり、迅速にリファクタリングできることを重視するか、追加のセーフティ ネットを用意するかが重要です。

于 2008-09-18T21:27:07.400 に答える
0

クラスの名前を非表示にしているため、スタイルに関するこの考え方は当てはまる場合と当てはまらない場合があります。

これら 2 つのオブジェクト MethodA と MethodB に "get" または "getAsConst" を指示することは理にかなっていますか? 「get」または「getAsConst」をどちらのオブジェクトにメッセージとして送信しますか?

私の見方では、メッセージの送信者/メソッドの呼び出し元として、あなたが値を取得しています。したがって、この「get」メッセージに応答して、何らかのメッセージを MethodA / MethodB に送信しています。その結果は、取得する必要がある値です。

例: たとえば、MethodA の呼び出し元が SOA のサービスで、MethodA がリポジトリの場合、サービスの get_A() 内で MethodA.find_A_by_criteria(...) を呼び出します。

于 2008-09-18T21:55:20.763 に答える
0

2 つ目はハンガリー語表記に関連するもので、個人的には好きではないので、最初方法を使用します。

ハンガリー語の表記法は、プログラミングで通常嫌いな冗長性を追加するため、好きではありません。それは私の意見です。

于 2008-09-18T21:43:13.460 に答える