[解決済み] リファレンスとポインタの使い分け
質問
ポインタと参照の構文と一般的な意味合いは理解していますが、APIで参照とポインタのどちらを使うのが適切か、どのように判断したらよいでしょうか?
当然ながら、状況によってはどちらか一方が必要です (
operator++
しかし、一般的には、ポインタ(およびconstポインタ)を使用することを好むと思います。
例えば、以下のようなコードで。
void add_one(int& n) { n += 1; }
void add_one(int* const n) { *n += 1; }
int main() {
int a = 0;
add_one(a); // Not clear that a may be modified
add_one(&a); // 'a' is clearly being passed destructively
}
ポインターを使えば、何が起こっているのかが常に(より)明らかなので、APIなどで分かりやすさが重視される場合には、リファレンスよりもポインターの方が適しているのではないでしょうか?つまり、リファレンスは必要なときだけ使うべきだということでしょうか(例.
operator++
)? また、どちらか一方を選択することでパフォーマンス上の懸念はありますか?
を編集します(古っ)。
NULL値を許容することと、生の配列を扱うことの他に、個人的な好みによるということになるようです。私は、以下の回答を受け入れました。 GoogleのC++スタイルガイド 参照は値の構文とポインタのセマンティクスを持つため、混乱する可能性がある」という見解が示されているからです。
NULLであってはならないポインタの引数をサニタイズするために必要な追加作業のため(例えば
add_one(0)
はポインターのバージョンを呼び出し、実行時に壊れます)。オブジェクトが存在しなければならない場所では参照を使用することは保守性の観点から理にかなっていますが、構文の明快さを失うのは残念です。
どのように解決するの?
できる限り参照を使い、必要な場合はポインタを使う。
ポインターは避けるべき。
その理由は、ポインターは他のどのような構成よりも、物事を追いかけ/読みにくくし、安全性を低下させ、はるかに危険な操作になるからです。
ですから、ポインターは他に選択の余地がない場合にのみ使用するのが鉄則です。
例えば、オブジェクトへのポインタを返すことは、関数がそのオブジェクトへのポインタを返すことができる場合に有効な選択肢となります。
nullptr
のように、場合によってはそうなることが想定されます。とはいえ、よりよい選択肢は、次のようなものを使うことでしょう。
std::optional
(C++17が必要。それ以前は
boost::optional
).
もう一つの例は、特定のメモリ操作のために生メモリへのポインタを使用することです。これは、コードベース全体の危険な部分を制限するのに役立つように、コードの非常に狭い部分に隠されて局所化されるべきです。
あなたの例では、ポインタを引数として使用する意味がありませんから。
-
を指定した場合
nullptr
を引数にとると、未定義ビヘイビアランドに突入してしまいます。 - の問題は、参照属性版では(簡単に見破れるようなトリックがなければ)許されない。
- 参照属性バージョンは、ユーザーにとってより理解しやすいものです:有効なオブジェクトを提供する必要があり、NULLの可能性があるものではありません。
もし関数の動作が与えられたオブジェクトの有無にかかわらず動作しなければならない場合、属性としてポインタを使用することで、そのオブジェクトに
nullptr
を引数にすれば、関数としては問題ない。これは、ユーザーと実装の間の契約みたいなものです。
関連
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] 仮想デストラクタはいつ使うのか?
-
[解決済み] C++でクラスと構造体はいつ使い分けるべきか?
-
[解決済み] 1行のifやループに中括弧(={})を使用する目的は何ですか?
-
[解決済み] なぜ 'this' はポインターで、参照ではないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された