一時的な変数をいつ使用する必要がありますか? [閉まっている
-
02-10-2019 - |
質問
具体的には、私はこれらのどれを書くべきか疑問に思っています:
{
shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock();
if (subMenu)
subMenu->setVisible(false);
}
また:
{
if (items[j].subMenu.lock())
items[j].subMenu.lock()->setVisible(false);
}
スタイルのガイドラインに従う必要はありません。最適化後、どちらの選択もパフォーマンスに違いがあるとは思わない。一般的に好ましいスタイルとは何ですか?
編集:アイテムのタイプ[j] .submenuはboost :: weak_ptrです。 lock()shared_ptrを作成します。実際には、上記の2つのバージョンには曖昧な違いがあります。一時的なshared_ptrがどれだけ長く続くかについて、{ブレース}に2つの例を巻き付けて、そこでのあいまいさを解決しました。
解決
別の方法:
if(shared_ptr<GuiContextMenu> subMenu = items[j].subMenu.lock()) {
subMenu->setVisible(false);
}
//subMenu is no longer in scope
私は仮定しています subMenu
aです weak_ptr
, 、その場合、2番目の方法は2つの時間的に作成されますが、これは問題である場合とそうでない場合があります。また、最初の方法は、必要以上に広いスコープに変数を追加します。個人的には、私は内部の割り当てを避けようとしています if
ステートメントですが、これは私が代替案よりも有用だと感じている数少ないケースの1つです。
他のヒント
の この特定のケース, 、 君 本当にすべきです 一時変数を使用してバージョンを使用します。その理由はパフォーマンスではなく、正確さです - 基本的に、あなたは2つが保証されていません x.lock()
呼び出しは同じ値を返します(例えば、別のスレッドが2つの呼び出しの間にオブジェクトの最後の強い参照を解放する場合)。一時的な変数に強力な参照を保持することにより、それが消えないようにします。
それ以外:
コンパイラは通常、副作用がないことが証明されていない限り(これを行うのが難しいが、属性が役立つ場合があります)、またはインラインドしている場合を除き、機能呼び出しを最適化することはできません。この場合、コールには副作用があります。
一時的な使用は、より短く、読みやすく、より保守可能なプログラムにつながる可能性があります(たとえば、エラーの場合、1つの場所で修正します)
どちらの選択も最適化後も違いはないことについてあなたは正しいと思います。
個人的には、コードをチェーンしたり、関数呼び出しを機能させるときなど、コードをより読みやすくする場合、新しい変数を宣言します。維持可能であり、コードが速度の違いなしで同じ効果を達成している限り、すべて読み取り可能なコードに要約されます。
編集:
Mmyersは良いコメントを買いました。はい、電話に注意してください lock()
一度だけでなく、2回。実装に応じてさまざまな効果があります。
選択は本質的にあなた次第ですが、あなたが注意すべき基本的なことは保守性です。
戻り値がブール値とは他のものである場合、中間変数に割り当てることで、デバッグを簡素化することがよくあります。たとえば、以下を踏み越えた場合:
if( fn() > 0 ) ...
事実の後にあなたが知っているのは、関数がゼロ未満またはゼロ以上の値を返すということだけでした。返品値が正しくなかったとしても、コードはまだ機能しているように見える場合があります。デバッガーで検査できる変数に割り当てると、返品値が予想されるかどうかを判断できます。
リターンがブール値の場合、実際の値はコードフローによって完全に暗黙的であるため、それほど重要ではありません。ただし、コードメンテナンスの下では、後でその結果が必要になる可能性があるため、いずれにせよ習慣にすることができます。
返品値がブール値であっても、考慮すべきもう1つの問題は、関数に副作用が必要かどうか、およびこれが短絡評価の影響を受ける可能性があるかどうかです。たとえば、声明の中で:
if( isValid && fn() ) ...
関数が呼ばれることはありませんisvalid is false。
不注意なプログラマー(そして多くの場合、メンテナンスタスクを取得するのは経験豊富なプログラマー)がメンテナンスしてコードを破壊する可能性がある状況は多く、おそらく避けられます。
この具体的な例では、それは何に依存していると思います lock()
します。機能は高価ですか?関数が呼び出されるたびに異なるものを返すことができますか(最初にポインターを返して、2回目にnulすることはできますか)? 2つの呼び出しの間でインターリーブする可能性のある別のスレッドが実行されていますか lock()
?
この例では、の行動を理解する必要があります lock()
そして、あなたのコードの残りの部分は、インテリジェントな決定を下します。
コードをより明確で読みやすくするため、エラーが発生しやすくなるため、最初の最初のものを好みます。たとえば、その2番目の例で括弧を忘れてしまいました:)この場合、実際には、おそらく2番目の例であなたがしたことをしますが、そのサブメニューを数回以上使用する必要がある場合は、一緒に行きます。コードを読みやすくする最初のもの。パフォーマンスに関しては、どんな正気なコンパイラでもそれを最適化できると思います(おそらく、パフォーマンスに違いがない理由です)。
また、Mmyersが指摘したように、それはLock()が何をするかにも依存します。一般的に、それが単純なゲッター方法などであれば、あなたは大丈夫でしょう。
あなたが好むものは何でも。私にとって、それは私がそれをどれだけ使用するかによって異なります。 2行については、両方の時間を書き出すだけですが、もっと使用すると変数を作成します。ただし、あなたはこのコードを維持し、それを見続ける必要がある可能性が高い人であるため、あなたのために機能するものは何でも使用してください。もちろん、コーディングガイドラインを持っている会社にいる場合は、それに従ってください。
好みのスタイルは、コードをより読みやすく保守できると思うスタイルだと思います。あなたが複数のチームである場合、他の唯一の考慮事項は、読みやすさとメンテナンスの容易さのために、誰もが同じスタイルを採用することを一般的に良い考えであることです。
この場合、一時的なものを使用する必要があると思います。 .lock()への実装が安価であることを知っていても、それは変化する可能性があります。 Lock()を2回呼び出す必要がない場合は、しないでください。ここでの値は、ロック()の実装からコードを切り離すことです。そして、それは一般的に良いことです。