私はシンプルで柔軟なイベントシステムをプログラムしようとしています(実際には、実際のイベントハンドラを持っている既存のライブラリがあると思います)。そして私はちょっとした障害に遭遇しました。呼び出し前にstd :: functionの有効性をチェックしますか?
代理人であるstd::function
(おそらくラムダを通して、おそらくはstd :: bindを介して)が有効な関数/メンバー関数のオブジェクトがそれを呼び出す前にまだ存在するかどうかを確認できますか?私は単にstd::function's
bool演算子を使ってみましたが、何の成功もありませんでした。
理想的にはA.デリゲート関数内以外の場所でチェックを行い、チェックされているstd ::関数がデリゲートでない場合でもB.が有効なコードを持っていることが理想的です。
アイデア?
編集:あなたはこの場合
#include <iostream> #include <string> #include <functional> #include <memory> class Obj { public: std::string foo; Obj(std::string foo) : foo(foo) {} void delegatedFn() { std::cout << foo << std::endl; } }; int main() { auto obj = std::make_shared<Obj>("bar"); std::weak_ptr<Obj> ptr = obj; std::function<void()> callback = [ptr](){ auto sh = ptr.lock(); if(sh) { std::cout << "valid" << std::endl; sh->delegatedFn(); } else { std::cout << "invalid" << std::endl; } }; callback(); obj = nullptr; callback(); return 0; }
:ここで私はあなたの代わりに裸なもののスマートポインタを(
std::shared_ptr
/
std::weak_ptr
)を使用することができます
#include <iostream>
#include <string>
#include <functional>
class Obj {
public:
std::string foo;
Obj(std::string foo) : foo(foo) {}
std::function<void()> getDelegate() {
auto callback = [this]() {this->delegatedFn();};
return callback;
}
void delegatedFn() {
std::cout << foo << std::endl;
}
};
int main() {
Obj* obj = new Obj("bar");
std::function<void()> callback = obj->getDelegate();
callback();
delete obj;
//perform some type of check here whether function is valid, without needing to know whether the function is a delegate or not
if(callback) {
std::cout << "Callback is valid" << std::endl; //callback is still considered valid after obj is deleted
callback(); //no exception thrown, prints a random series of characters
}
else {
std::cout << "Callback is invalid" << std::endl;
}
return 0;
}
お試しいただいた内容をお見せできますか?好ましくは、[最小限の完全かつ検証可能な例](http://stackoverflow.com/help/mcve)。また、あなたが得るどんな誤りも含みます。 –
ランダムなポインタが有効なオブジェクトを指しているかどうかをチェックすることはできません。ユースケースは同じものになります。 –
あなたのサンプルコードを見てから、これは、 'Obj'クラスがメンバ変数' foo'へのポインタを返した関数を持っていて、 'Obj'クラスの後に' 「obj」が削除されました。可能な唯一のことは、あなた自身でそれを追跡することです。ライブラリーやコンパイラーがここで助けてくれる "魔法"はありません。 –