関数に使用する元の変数を与えるときのより良い方法は次のとおりです。
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
-- correctにしてください。
const
指定子を欠くことができることを意味します。値0/NULLが現在のコンテキストで有効な入力である場合のみ、ポインターで値を渡します。
理由1:呼び出し元として、must beで渡すものはすべて使用可能な状態であることがわかります。
理論的根拠2:calledとして、あなたはisが使用可能な状態にあることを知っています。したがって、その値に対して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);
}
ポインタ
現在、有効なメモリ位置を指し示していないポインターには、値nullが与えられます(これはゼロです)
BaseType* ptrBaseType;
BaseType objBaseType;
ptrBaseType = &objBaseType;
&は、オペランドのメモリアドレスを返す単項演算子です。
間接参照演算子(*)は、ポインターが指す変数に格納されている値にアクセスするために使用されます。
int nVar = 7;
int* ptrVar = &nVar;
int nVar2 = *ptrVar;
参照
参照(&)は、既存の変数のエイリアスのようなものです。
参照(&)は、自動的に逆参照される定数ポインターのようなものです。
通常、関数の引数リストと関数の戻り値に使用されます。
参照は作成時に初期化する必要があります。
参照がオブジェクトに初期化されると、別のオブジェクトを参照するように変更することはできません。
NULL参照を持つことはできません。
Const参照はconst intを参照できます。 constの値を持つ一時変数で行われます
int i = 3; //integer declaration
int * pi = &i; //pi points to the integer i
int& ri = i; //ri is refers to integer i – creation of reference and initialization
可能な場合は参照を使用し、必要な場合はポインターを使用します。 C++ FAQ:「いつ参照を使用し、ポインタを使用する必要がありますか?」
C#のoutキーワードを検討してください。コンパイラーは、メソッドの呼び出し元がoutキーワードをout引数に適用することを要求します(out引数が既にある場合は知っていますが)。これは読みやすさを高めることを目的としています。最近のIDEでは、これは構文(またはセマンティック)強調表示の仕事だと思う傾向があります。
ポインター:
nullptr
(またはNULL
)を割り当てることができます。&
を使用する必要があり、明示的にオブジェクトを変更します。参照:
&
を明示的に使用する必要はありません。パラメーターが変更されているかどうかを確認するには、関数の実装に移動する必要があるため、これは時々悪いと見なされます。渡すコンテンツを変更/保持したい理由がない限り、const参照で渡します。
ほとんどの場合、これが最も効率的な方法です。
変更したくない各パラメーターでconstを使用することを確認してください。これは、関数で愚かなことを行うことを防ぐだけでなく、渡された値に対して関数が何をするかを適切に示します。これには、指すものだけを変更したい場合にポインターconstを作成することが含まれます.
参照はポインターに似ていますが、参照によって参照される値にアクセスするためにプレフィックス∗を使用する必要がない点が異なります。また、初期化後に別のオブジェクトを参照する参照を作成することはできません。
参照は、関数の引数を指定するのに特に役立ちます。
詳細については、「Bjarne Stroustrup」による「C++のツアー」(2014)11〜12ページを参照してください。