0

全て、

最近、この質問を DAL 設計に投稿しました。そのことから、オブジェクトへの参照を関数に渡し、その関数でそのオブジェクトに値を設定することは、C++ データ アクセス レイヤーの適切なインターフェイスになるように思われます。

  bool DAL::loadCar(int id, Car& car) {} 

boost::shared_ptr への参照を使用する方が良いかどうか疑問に思っています。

  bool DAL::loadCar(int id, boost::shared_ptr<Car> &car)

何かご意見は?一方が他方よりも優れているか?

両方の呼び出しに const の正確性を適用すると、どのような影響がありますか?

前もって感謝します。

4

4 に答える 4

4

sbiが言うように、「関数が何をするかによります。」

ただし、上記の最も重要な側面は、NULL が許可されているかどうかではなく、関数が後で使用するためにオブジェクトへのポインターを格納するかどうかだと思います。関数が一部のデータを入力するだけの場合、次の理由で参照を使用します。

  • この関数は、shared_ptr を使用していないクライアント、スタック オブジェクトなどに使用されているクライアントでも引き続き使用できます。
  • shared_ptrで関数を使用することはまだ簡単です-shared_ptrには参照を返す逆参照演算子があります
  • NULL を渡すことはできません
  • タイピングが少ない
  • 必要がないときに「もの」を使うのは好きではない

関数が後で使用するためにポインターを格納する必要がある場合、またはポインターの格納が必要になるような方法で関数が変更されることが予想される場合は、shared_ptr を使用します。

于 2009-10-09T10:17:00.900 に答える
3

それは関数が何をするかに依存します。

一般に、ポインターを受け取る関数は、呼び出すオブジェクトがなくても呼び出し元がこの関数を呼び出す可能性があることを示します。呼び出し元はいつでも渡すことができますNULL。それが関数の仕様に適合する場合は、(スマート)ポインターを使用します。参照カウントスマートポインターをコピーする代わりに参照で渡すことは最適化です(時期尚早ではありません。追加する必要があります)。これは、MT環境では、パフォーマンスに顕著な影響を与える可能性のある参照カウントの不必要な増減を回避するためです。

非定数参照を引数として取る関数は、変更される可能性のある有効なオブジェクトが渡されることを期待しています。呼び出し元は、有効なオブジェクトがない限り、その関数を(合法的に)呼び出すことはできません。また、関数にオブジェクトの状態を変更させる意思がない限り、呼び出し元は呼び出しません。それが関数の仕様によりよく適合する場合は、参照を使用してください。

于 2009-10-09T09:45:14.847 に答える
1

有効なオブジェクトを受け取る必要がある場合 (つまり、呼び出し元に NULL を渡させたくない場合) は、絶対に boost::shared_ptr を使用しないでください。2番目の例は、「スマートポインター」への参照を渡します...詳細を無視すると、「車へのポインターへのポインター」です。これは参照であるため、shared_ptr オブジェクトを NULL にすることはできません....しかし、NULL 値 (つまり、「null」オブジェクトを指す) を持つことができないという意味ではありません。

スマートポインターへの参照が「より良い」と考える理由が正確にはわかりません-呼び出し元関数は既にスマートポインターを使用していますか?

「const」の意味については...次のような意味ですか

bool DAL::loadCar(int id, const Car& car) {}

? はいの場合、それは非生産的です。「car」が変更されないという事実をコンパイラに伝えます(ただし、おそらく変更したいでしょう!)。

それとも、関数を「const」にするつもりですか?

class DAL{
   bool loadCar(int id, Car& car) const;
}

?

後者の場合、メソッド「loadCar」が DAL オブジェクトを変更しないことをコンパイラ/API ユーザーに伝えます。これが当てはまる場合は、そうすることをお勧めします。これにより、コンパイラの最適化が有効になるだけでなく、「コントラクト」(関数シグネチャ) で、関数が DAL を変更しないことを指定することをお勧めします。コードでこの暗黙の仮定を作成します (このようにして、これが真のままであることを確認し、将来、「DAL」オブジェクトを変更する方法で「loadCar」関数を変更する人がいないことを確認します)

于 2009-10-09T10:15:19.563 に答える
0

最初のケースでは、単純に Car を渡し、情報を「入力」します。たとえば、「デフォルト」の車を作成してから埋めることができます。これには 1 つの不都合が見られます: Car の 2 つのクラスを持つことはあまりオブジェクト指向ではありません。私にとって、車は車であるため、関数の前後で有効な車 (たとえば、場所 A から B まで運転できる車; 加速、ブレーキ、発進、停止できる車) である必要があります。

私は通常、ブーストではなく従来のポインターを使用するため (ちなみに問題はありません)、後者の代替案についてコメントすることはできません。

于 2009-10-09T09:34:26.767 に答える