1

C++ で、別のオブジェクトへのポインターを返すヘルパー クラスのメソッドがあるとします。メソッドのシグネチャと返されるオブジェクトの型を除いて、このメソッドに関する情報はありません。この場合、メモリ管理を行う方法は?

以下のこの関数としてスマートポインターを使用しようとしました:

void f() {
   auto_ptr<SomeClass> p_someClass = p_Helper->getSomeclass();
   p_someClass->doSomething();
}

p_someClass に割り当てられたメモリは、 f() がスコープ外になるとすぐに解放されます。しかし、getSomeclass() が新しいメモリを割り当てず、単に「シングルトン」ポインターを返す場合 (p_Helper もシングルトンである場合) はどうなるでしょうか。次に p_Helper->getSomeclass() を呼び出すと問題が発生します。

この問題を処理する通常の方法は何ですか? 特に Helper クラスに関するドキュメントがほとんどない場合は?

4

5 に答える 5

3

ヘルパー クラスのドキュメントには何と書かれていますか? それが究極の問題です。有効期間を指定せずにポインターまたは参照を返すことはできません。それがクラス内の何かへのポインターである場合、それはクラス オブジェクトの有効期間である可能性がありますが、静的な有効期間 (プログラムの終了まで) を持つこともできます。 —これは、文字列リテラルを として返す関数の場合ですchar const*)、有効期間が短くなる可能性があります (たとえば operator[]、標準ライブラリ コンテナーによって返される参照)、またはヘルパーが削除を期待する可能性があります。ただし、後者は純粋な C++ ではまれです。そのような場合の慣例は、返すことですstd::auto_ptr(または std::unique_ptr非常に最新のコンパイラを使用している場合)。(C では、返されたポインタを、それを返すライブラリ内の特定の関数を呼び出すことによって解放する必要があることを文書化することがよくありました。デストラクタがなければ、最後に制御を取り戻すために何かをする必要があります。)

ドキュメントがないので、ライブラリは使用できないと言いたくなります。それでも...内部の何かを指し、クラスの寿命があると仮定するのがおそらく最も合理的な推測です。これは、プログラマーが文書化するのを最も忘れやすいケースです。それを削除するか、それを削除するスマートポインタに置くことは、おそらく良い考えではありません.所有権の問題については十分に述べられているため、削除することになった場合にクラスの作成者が事実を文書化することに失敗する可能性は低いと思われます. . (ただし、削除することになっていない場合でも、寿命の問題は残ることに注意してください。)

于 2012-07-18T07:30:07.137 に答える
2

あなたが p_Helper クラスの作成者でない場合は、最初に:

通常、シングルトンにはパブリック デストラクタがないため、その場合はコンパイルされません。

第 2 に、それ以上の情報なしで裸のポインターを「取得」した場合、それを削除できるかどうかを知る方法はありません。関数/メソッドを使用するには、その情報をドキュメントで提供する必要があります。

p_Helperを設計している場合は、ベア ポインターではなく、スマート ポインターを返すようにします。メソッドが呼び出しごとに新しいリソースを作成する場合は、unique_ptrこちらをご覧ください: unique_ptr と shared_ptr の違い

于 2012-07-18T07:13:04.417 に答える
1

このシナリオへの典型的なアプローチは、参照カウントを使用することであり、そのようなスマート ポインターshared_ptrは通常、すべての妥当なケースを処理します。

于 2012-07-18T07:13:27.150 に答える
1

簡単なテストを行い、p_Helper->getSomeclass(); への 2 つの呼び出しによって返されるポインターを比較できます。

bool do_not_delete =  p_Helper->getSomeclass() ==  p_Helper->getSomeclass();

両方のポインターが等しい場合、(おそらくオプションの) 参照を意味するポインターを取得する可能性があります。

hth トルステン

于 2012-07-18T07:39:34.410 に答える
1

この場合、生のポインターを使用できます。

void f() {
   SomeClass *p_someClass = p_Helper->getSomeclass();
   p_someClass->doSomething();
}
于 2012-07-18T07:14:32.980 に答える