関数に元の変数を指定して操作する場合のより良い方法は次のとおりです。
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
また:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
IOW:どちらかを選ぶ理由はありますか?
私の経験則は次のとおりです。
ポインターを使用してポインター演算を実行する場合(たとえば、配列をステップスルーするためにポインターアドレスをインクリメントする場合)、またはNULLポインターを渡す必要がある場合は、ポインターを使用します。
それ以外の場合は参照を使用してください。
次の関数呼び出しのコーディング ガイドラインを確立することでメリットが得られると思います。
他のすべての場所と同様に、常にconst
正確であること。
const
指定子を欠いている可能性があることを意味します。値 0/NULL が現在のコンテキストで有効な入力である場合にのみ、ポインターによって値を渡します。
根拠 1: caller として、渡すものはすべて使用可能な状態でなければならないことがわかります。
根拠 2:と呼ばれるように、入ってくるものは何でも使用可能な状態にあることがわかっています。したがって、その値に対して NULL チェックやエラー処理を行う必要はありません。
根拠 3: 根拠 1 と 2 はコンパイラによって強制されます。可能であれば、コンパイル時に常にエラーをキャッチしてください。
関数の引数が out-value の場合は、参照によって渡します。
値が POD ( Plain old Datastructure ) であるか、十分に小さい (メモリの観点から) 場合、または他の方法で (時間の観点から) コピーするのに十分安価な場合にのみ、[const 参照による受け渡し] ではなく [値による受け渡し] を選択します。
これは最終的には主観的なものになります。ここまでの議論は役に立ちますが、これに対する正しい答えや決定的な答えはないと思います。多くは、スタイルのガイドラインとその時点でのニーズによって異なります。
ポインターにはいくつかの異なる機能 (何かを NULL にすることができるかどうか) がありますが、出力パラメーターの実際の最大の違いは純粋に構文です。たとえば、Google の C++ スタイル ガイド ( https://google.github.io/styleguide/cppguide.html#Reference_Arguments ) は、出力パラメーターのポインターのみを義務付け、const である参照のみを許可します。その理由は読みやすさの 1 つです。値の構文を持つものには、ポインターのセマンティックな意味があってはなりません。これが必ずしも正しいか間違っているかを示唆しているわけではありませんが、ここでのポイントは、正確さではなく、スタイルの問題だということだと思います.
変数の値を変更する場合は、ポインターを渡す必要があります。技術的には参照またはポインターを渡すことは同じですが、ユースケースでポインターを渡すと、関数によって値が変更されるという事実が「アドバタイズ」されるため、より読みやすくなります。
値が存在しないことを示す必要があるパラメーターがある場合は、パラメーターをポインター値にして NULL を渡すのが一般的です。
ほとんどの場合 (安全性の観点から) より良い解決策は、boost::optionalを使用することです。これにより、オプションの値を参照によって渡すことも、戻り値として渡すこともできます。
// Sample method using optional as input parameter
void PrintOptional(const boost::optional<std::string>& optional_str)
{
if (optional_str)
{
cout << *optional_str << std::endl;
}
else
{
cout << "(no string)" << std::endl;
}
}
// Sample method using optional as return value
boost::optional<int> ReturnOptional(bool return_nothing)
{
if (return_nothing)
{
return boost::optional<int>();
}
return boost::optional<int>(42);
}
可能な場合は参照を使用し、必要な場合はポインターを使用します。C++ の FAQから: 「いつ参照を使用する必要があり、いつポインターを使用する必要がありますか?」
C#のoutキーワードを考えてみましょう。コンパイラーは、メソッドの呼び出し元がoutキーワードをout argsに適用する必要がありますが、それらが既に認識されている場合でも同様です。これは、読みやすさを向上させることを目的としています。最近のIDEでは、これは構文(またはセマンティック)の強調表示の仕事だと思う傾向があります。
参照は暗黙のポインターです。基本的に、参照が指す値を変更できますが、参照を別のものに変更することはできません。したがって、私の 2 セントは、パラメーターの値を変更するだけの場合は参照として渡しますが、パラメーターを変更して別のオブジェクトを指すようにする必要がある場合は、ポインターを使用して渡します。
ポインター:
nullptr
(またはNULL
)。&
、型がポインター自体ではない場合に使用する必要があり、オブジェクトを変更していることを明示的にします。参考文献:
&
。パラメータが変更されているかどうかを確認するには、関数の実装に移動する必要があるため、これは時々悪いと見なされます。渡す内容を変更/保持する理由がない限り、const 参照で渡します。
ほとんどの場合、これが最も効率的な方法です。
変更したくない各パラメーターで必ず const を使用してください。これにより、関数内で愚かなことをするのを防ぐだけでなく、関数が渡された値に対して何をするかを他のユーザーに示すことができます。これには、指している内容のみを変更したい場合にポインター const を作成することが含まれます...