機能する元の変数を関数に与える場合のより良い実践とは:
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
または:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
IOW:別のものを選ぶ理由はありますか?
機能する元の変数を関数に与える場合のより良い実践とは:
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
または:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
IOW:別のものを選ぶ理由はありますか?
回答:
私の経験則は:
それらを使用してポインタ演算を実行する場合(たとえば、ポインタアドレスをインクリメントして配列をステップスルーする場合)、またはNULLポインタを渡す必要がある場合は、ポインタを使用します。
それ以外の場合は参照を使用します。
Base* b = new Derived()
)?これは、ポインターなしでは処理できないケースのようです。
次の関数呼び出しのコーディングガイドラインを確立することでメリットが得られると思います。
他のすべての場所と同様に、常に- const
正しいこと。
const
指定子を欠くことを意味します。値0 / NULLが現在のコンテキストで有効な入力である場合にのみ、ポインターによって値を渡します。
理論的根拠1:呼び出し元として、渡したものはすべて使用可能な状態でなければならないことがわかります。
理由2:としては、と呼ばれるあなたが来るものは何でもそれは知っている、ある使用可能な状態に。したがって、その値に対してNULLチェックやエラー処理を行う必要はありません。
根拠3:根拠1と2はコンパイラーによって強制されます。可能であれば、コンパイル時に常にエラーをキャッチします。
関数の引数がout-valueの場合は、参照によって渡します。
値がPOD(Plain old Datastructure)、または十分に小さい(メモリの観点から)、または他の方法で十分に安価(時間の観点から)でコピーできる場合にのみ、「pass by const reference」より「pass by value」を選択します。
std::vector<>
。
これは最終的には主観的です。これまでの議論は有用ですが、これに対する正しいまたは決定的な答えはないと思います。多くは、スタイルガイドラインとそのときのニーズによって異なります。
ポインターにはいくつかの異なる機能(何かがNULLであるかどうかにかかわらず)がありますが、出力パラメーターの実際的な最大の違いは純粋に構文です。たとえば、GoogleのC ++スタイルガイド(https://google.github.io/styleguide/cppguide.html#Reference_Arguments)では、出力パラメーターのポインターのみが要求され、constの参照のみが許可されます。推論は読みやすさの1つです。値の構文を持つものは、ポインタの意味論的な意味を持つべきではありません。これが必ずしも正しいか間違っているかを示唆しているわけではありませんが、ここでのポイントは、それがスタイルの問題であり、正確さの問題ではないということです。
変数の値を変更する場合は、ポインターを渡す必要があります。技術的に参照またはポインターを渡すことは同じですが、ユースケースでポインターを渡すと、関数によって値が変更されることを「アドバタイズ」するため、より読みやすくなります。
const
または非const
参照が、パラメータのは、ALA渡されたかどうかを確認することができます&x
対x
、および使用をパラメータが変更される可能性があるかどうかをエンコードするための変換。(とconst
はいえ、ポインターを渡したい場合があるので、コンテンションはヒントにすぎません。何かが変更されないかもしれないという疑いは、それがいつになるかを考えるよりも危険ではありません。 ....)
値がないことを示す必要がある可能性のあるパラメーターがある場合、パラメーターをポインター値にして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から:「いつ参照を使用する必要があり、いつポインタを使用する必要がありますか?」
ポインタ
現在有効なメモリ位置を指し示していないポインタには、値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
参照は暗黙のポインタです。基本的に、参照が指す値を変更できますが、参照を他の何かを指すように変更することはできません。したがって、私の2セントは、パラメーターの値を変更するだけの場合は参照として渡しますが、別のオブジェクトを指すようにパラメーターを変更する必要がある場合は、ポインターを使用して渡します。
C#のoutキーワードを検討してください。コンパイラーは、メソッドの呼び出し元がout引数にoutキーワードを適用する必要があります。これは読みやすさを向上させることを目的としています。最近のIDEでは、これは構文(またはセマンティック)強調表示の仕事だと思いがちです。
ポインタ:
nullptr
(またはNULL
)。&
は、型がポインタ自体ではない場合に使用し、オブジェクトを明示的に変更する必要があります。参照:
&
。パラメータが変更されているかどうかを確認するには、関数の実装に移動する必要があるため、これは時々悪いと考えられます。