私がやりたいことは、小さなマネージャー/ハンドラー クラスを作成することです。Manager は、Handle を配布および管理します。このようなハンドルは、たとえば単純なファイルハンドルです。
コンシューマーが既に存在するハンドルを取得したい場合、マネージャーは単純に shared_ptr を返します。ハンドルが存在しない場合、マネージャは新しいハンドルを作成してから、shared_ptr を返します。
Manager 内では、これらの shared_ptr は単純な STL-Map に格納されます。割り当てられた最後の shared_ptr が削除された場合、マネージャーに関連するマップ要素を削除して、ハンドラー オブジェクトが自動的に破棄されるようにします。
これはガベージ コレクション (たとえば、ポインターの使用回数をチェックするワーカー スレッド) のように聞こえますが、よりエレガントに実行できると確信しています。
manager インスタンスの参照を handler オブジェクトに渡すにはどうすればよいですか? (たとえば、unique_ptr(this) を新しいハンドラーのコンストラクターに渡すようなもの)
#include <memory>
#include <iostream>
#include <map>
using namespace std;
/*
* Simple handler class, that actually does nothing.
* This could be e.g. a Filehandler class or sth. like that
*/
class Handler {
private:
int i;
public:
Handler(int i) :i(i) {}
~Handler() {}
// Say who you are.
void print(void) { cout << "I am handler # " << i << endl; }
};
/*
* This is the "manager" class, that manages all handles. A handle is identified
* by an integer value. If a handle already exists, the Manager returns a shared_ptr,
* if it does not exist, the manager creates a new handle.
*/
class Manager {
private:
map<int, shared_ptr<Handler> > handles;
public:
Manager() {}
~Manager() {}
shared_ptr<Handler> get_handler(int identifier) {
shared_ptr<Handler> retval;
auto it = handles.find(identifier);
if(it != handles.end() ) {
retval = it->second;
} else {
retval = shared_ptr<Handler>(new Handler(identifier));
handles.insert( pair<int, shared_ptr<Handler>>(identifier, retval) );
}
return retval;
}
};
int main(int argc, char** argv) {
Manager m;
// Handler 13 doesn't exist, so it gets allocated
auto h = m.get_handler(13);
// Manager knows about handler 13, so it returns the already existing shared_ptr
auto i = m.get_handler(13);
h.reset(); // Well... Let's assume we don't need h any more...
// do some stuff...
i->print();
// ...
i.reset(); // We also loose i. This is exactly the point where i want the manager to forget about the handle 13
return 0;
}