2009-10-05 15 views
5

に渡された移入[EDIT 1 - 追加第三ポインタの構文(おかげでアレックス)]C++ DAL - リターンリファレンスまたはリファレンス

あなたがDALのために好むと理由のうちしまう方法:

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

車の最初のメソッドが見つからない場合はnullを返し、2番目のメソッドはfalseを返します。

2番目の方法は、ヒープ上にCarオブジェクトを作成し、データベースからクエリされたデータを取り込みます。第二は間違いなく望ましい

Car& DAL::loadCar(int id) 
{ 
    Car *carPtr = new Car(); 
    Car &car= *carPtr; 
    car.setModel(/* value from database */); 
    car.setEngineSize(/* value from database */); 
    // etc 
    return car; 
} 

おかげ

答えて

5

:おそらくの線に沿ってコードを意味している(私のC++は非常に錆びています)。あなたはnew'dされているオブジェクトへの参照を返しています。ソフトウェアを使用するエンドユーザにとって、返されたオブジェクトが削除を必要とすることは明らかではない。ユーザーがこのようなことをした場合にプラス

Car myCar = dal.loadCar(id); 

ポインタが失われます。

したがって、2番目の方法はメモリの制御を呼び出し元に置き、奇妙な間違いが発生するのを止めます。

編集:参照による返品は賢明ですが、親(つまりDAL)クラスが参照の有効期間を管理している場合のみです。 DALクラスにCarオブジェクトのベクトルがある場合、参照を返すことは完全に分かりやすいことです。

編集2:私はまだ2番目の設定を好みます。 3番目は最初のものよりはるかに優れていますが、呼び出し元にオブジェクトが初期化されていると仮定させることになります。

また

Car DAL::loadCar(int id); 

を提供することができそして希望は、スタックのコピーを受け入れます。

また、ある種のnull carオブジェクトを作成して、 "有効"なishオブジェクトを返すことができますが、すべてのフィールドで有用な情報を返さないことを忘れないでください(したがって、明らかにデータをゴミ箱に初期化します)。これがヌルオブジェクトパターンです。

+0

ありがとうございました。呼び出し元が "Car&myCar = dal.loadCar(id)"と書いたとしても、ポインタは失われませんか?とにかくDAL以外のコードがDALによって作成されたメモリを削除するのですか? – ng5000

+0

いいえ、あなたが書いたものをあなたが書き込んだのであれば、メモリは "できました"ということができます。あなたは非常に奇妙に見える..しかしそれを行うには、 "削除&myCar;"を呼び出す必要があります。 – Goz

+0

スタックコピーは起こらないかもしれません。コンパイラと最適化によって、(N)RVOは#1と同等の動作をします。いずれにせよ、車が見つからないときに例外を投げることが必要である。 –

4

なぜなら、ヒープ上にオブジェクトを割り当てているので、問題が発生した場合にNULLを返すCar * LoadCar()を考慮しないでください。このようにして、参照型(それぞれの参照を初期化する必要があります)に制限はなく、エラーケースを通知する手段もあります。

+0

3番目のオプションを追加するのに合理的で更新された質問が聞こえます。 – ng5000

+0

Car&DAL :: loadCar(int id)はNULLを返すことはできません。ヌル参照はなく、ヌルポインタのみです。 – Massa

関連する問題