2016-12-19 7 views
0

ポインタに関する小さな問題が発生しました。 私は1行でこのタスクを実行するために迅速かつ簡単な方法を持っていると思ったよう:ポインタを削除してリセットするためのC++テンプレート関数

... 
delete pointer; 
pointer = 0; 
... 

私はすぐにポインタのいずれかのタイプを受け入れるテンプレートメソッドを持つ単純なヘッダファイルを設定します。これは次のようになります:

#ifndef P_DELETE_H 
#define P_DELETE_H 

template <typename T> 
void pDelete(T* pointer) { 
    if (pointer) { 
    delete pointer; 
    pointer = 0; 
    } 
} 

#endif 

しかし、結果は、オブジェクトbeeingが削除され、ポインタbeeingリセットの私の期待を満たしていません。代わりに、オブジェクトだけが削除されたようですが、ゼロに設定しても何の効果もありませんでした。誰かがここで私を少し明るくしてこの行動を説明できたら、私はそれほど気にしません!

UPDATE:

答えがのstd :: unique_ptrをとstdを使用して、説明したよう:: shared_ptrのは、このポインタをより無効化して行くための安全な方法です。

しかし、あなたは本当に私が要求されるような道を行く必要がある場合は、次のコードは、トリックを行います:

template <typename T> 
inline void pDelete(T*& pointer) { 
    if (pointer) { 
    delete pointer; 
    pointer = 0; 
    } 
} 

しかし、これは正しく削除し、ポインタを無効にもかかわらず、使用することが一般的に安全ではありませんすべてのインスタンスで(クイックテストはこれを明らかにした)。

有益な回答をいただき、ありがとうございます。あなたが探している

+2

関数引数は、関数スコープに対してローカルです。これにはポインタが含まれます。関数外の値に影響を与えるには、ポインタ参照またはポインタポインタを使用する必要があります。 – Biffen

+0

参照パラメータが必要です: 'void pDelete(T *&pointer)' –

+0

*参考文献*と引数の受け渡し方法について知っていますか? *参照によって*? –

答えて

6

解決策は以下のとおりです。

delete pointer; 
pointer = nullptr; 

うん、ちょうどインラインそのコードを記述します。他の関数テンプレートを導入して、実際に何を理解して、1行のコードを保存するかを人々が調べなければならない理由はまったくありません。

上記は完全に読みやすく、わかりやすいです。

+0

しかし、上記のことはかなり疑問だと言及することを忘れてしまいます。削除後にポインタをヌルにすると、自動的に無効になります。 – SergeyA

+2

@ SergeyAもちろん利点があります。通常、あなたはその利益を必要としません。なぜなら、それらが自動的に無効にならない理由です。 – Barry

+0

「通常、あなたは利益を必要としません」 - 正確に。 – SergeyA

1

あなたがしようとしていることはすべて嘘です。これがなぜ自動的に起こっていないのか考えましたか?なぜランタイムは削除後にポインタを無効にしませんか? C++標準委員会は十分にスマートではなかったので?

いいえ、あなたはほとんどの時間のためによくありません。はい、あなたはこのポインタのインスタンスを無効にします - しかし、あなたがポインタを持っていた全理由が、このポインタが他の場所にうまく生きている可能性が高いです! (もちろんこれには例外があります)。その結果、無効化されたすべての無効化はポインタのこのインスタンスでの不正アクセスですが、他のインスタンスでは無効になります。本質的に、それはあなたに誤った安全感を与えます。

自動ポインタの使用を誤った感じにする代わりに、std::unique_ptrを最初に選択してください。十分でない場合は、std::shared_ptr - 本当に必要なことを確認してください。

+0

shared_ptrをQTで一番うまく使う方法を教えてもらえれば、今すぐ使ってみましょう。 私はそれが安全でクリーンな方法であることを認識していますが、qt関数を必要とするところでは私にとって意味がないようです。 – Migsi

+0

@Migsi、私はQtについてよく分かりませんが、私が理解する限り、Qtにはそれ自体のスマートポインタ機能がありますか? – SergeyA

+1

@MigsiもしQTオブジェクトを扱うときに 'delete'を直接呼び出すのであれば、' std :: unique_ptr'と 'std :: shared_ptr'で通常使われているのと同じパターンがあなたの状況。 – Xirema

1

所有権を示すために生ポインタを使用しないようにしてください。ポインタを使用してオブジェクトの所有権を取得する場合は、std::unique_ptrに移動する必要があります。

あなたの状況はpointer.reset()です。

あなたが所有するオブジェクトを他のコードが観察できるようにするには、pointer.get()を使用して非所有ポインターを取得します。 *pointerを使用して参照を取得することもできます。

生ポインタ(私はあなたのQtを見ています)を使用するインターフェイスでその所有権を渡す必要がある場合は、pointer.release()を使用してください。

+0

QTに入っているすべてのポインタを ".release()"しますか?また、いつ私がQTに与えるか、またはQTから得るポインタについて気にする必要がありますか?ドキュメントはしばしばこれをかなり不明瞭にしています。 – Migsi

+2

生ポインタの前に不明な点があった場合は、漏れか二重削除のいずれかでした。その点で何も変わっていません。 Qtは一般に、 "親/子"関係のミューテータのポインタを介してのみ所有権を譲渡します – Caleth

関連する問題