2

私は次の構造を持っています(簡略化):

class myType
{
    static char* data;
    //more private data here
public:
    //public interface here
};

dataのすべてのインスタンス間で共有されるリソースでmyTypeあり、動的に割り当てられたメモリ (初期化時にいずれかのインスタンスによって割り当てられる) を指します。

ここまでは順調ですね。が指すメモリを解放する必要があるときに問題が発生しdataます。参照カウントはここでは解決策ではありません。myTypeこれは、実行のある時点で のインスタンスが 1 つも存在しない可能性があり、後で新しいインスタンスを作成できるため、data永続化する必要があるためです。

ドライバーのアンロード時にそのメモリを解放する必要がありますが、アンロードはmyTypeオブジェクトの実際の破壊とは関係がないため、data手動で解放する必要があります。これは受け入れられますが、アンロード ハンドラからはアクセスできませんdata(そうあるべきです) 。private確かに、内部でstaticand関数を作成することはできますが、それは正しくないようです。結局のところ、イニシャライザは必要なかったのに、なぜメモリを解放するために必要なのでしょうか? そのデータは、外部インスタンスからアクセスできないようにする必要があります。public destroymyTypepublicmyType

この件に関する洞察をいただければ幸いです。

4

3 に答える 3

3

コードの複雑さに応じて、次の 2 つのオプションのいずれかを優先します。

  1. destroyMetadata実行中にインスタンスが作成された場合に呼び出す必要がある静的パブリックメソッドを用意します。個人的には、暗黙的に作成されたデータを破棄する方法があることに特に悪い点はありません。このアプローチの問題は、それが手動のアプローチであるため、バグが発生しやすいことです。
  2. クリーンアップ時に実行されるコールバックを登録できる (シングルトンの) Unload-Handler を作成します。次に、プライベートな静的メソッドを作成し、最初に作成されたdestroyMetadataときにハンドラーに登録できます。dataこれは少し手間がかかりますが、全体的にすっきりしたデザインになります。

これら 2 つのどちらが適切かは、クリーンアップがどれほど複雑になるかによって異なります。カスタム クリーンアップを使用するクラスが多数ある場合は、カプセル化が向上し、全体的にコードがクリーンになるため、2 番目のオプションが望ましいと思われます。ただし、これがコードの唯一の部分であり、そのようなクリーンアップが必要な場合、そのような一般化されたハンドラー (YAGNI) を記述するのは少しやり過ぎです。したがって、最初のアプローチは、概念的には面倒ですが、そのシナリオでははるかに優れています。

于 2013-05-05T10:56:51.750 に答える
1

パブリックイニシャライザを割り当てる必要がないことは、それを解放することに関しては無関係です-最初の使用時に割り当てるのは簡単です。なぜなら、そこにある必要があることを知っているコードを実行しているためです(if (data==NULL) data=new. ..)、しかし、デストラクタでこれが意味をなさない場合、メモリが確実に返されるようにする場合は、パブリック デアロケータが必要になる場合があります。

別の可能性 (あなたの場合に意味がある場合) は、コンストラクターでインクリメントされ、デストラクタでデクリメントされる参照カウントですが、カウントがゼロに達してもすぐに割り当てを解除しないでください。代わりに、特定の「クールダウン」期間後に割り当てを解除するようにタイマーを設定できます。このタイマーが起動する前にコンストラクター (または遅延してメモリを割り当てるその他のコード) が呼び出された場合、再割り当てではなくタイマーをキャンセルしますが、タイマーが起動すると、割り当てが解除されます。

于 2013-05-05T10:54:58.810 に答える
1

なぜpublic staticdestroy関数が正しくないように見えるのかわかりません。あなた自身が主張しているように、必要な破壊の瞬間と、オブジェクトとそのインスタンス自体の寿命との間に関係はありません。そのため、タイムリーな破壊の責任を外部エンティティに負わせているため、論理的にアクセスできる必要があります。その場合、このpublic staticアプローチは最も理にかなっています。そのように、それは一種の薄いガベージコレクターです。

この決定を行う必要があるという点で、基礎となるアーキテクチャに欠陥があると思います。データコンテナは、適切なライフサイクル制御と実際のガベージコレクタを備えた、適切に参照カウントされた別のクラスでなければなりませんが、それはコードの残りの部分に依存します。説明されている解決策が最適である可能性があります。

于 2013-05-05T10:55:12.587 に答える