私は自分のファンクタにHttpRequestオブジェクト(Cocos2d-xから)をラップしようとしています。私のファンクタに渡されたコールバックを呼び出す以外はすべて正常に動作しています。あなたは下のクラスでエラーを見つけられますか? (私はコードの関連部分のみを貼り付けた)。Functorを使用したコールバックパターン
Cloud.hpp:
#ifndef Cloud_hpp
#define Cloud_hpp
#include "external/json/document.h"
#include "network/HttpClient.h"
using namespace cocos2d::network;
typedef std::function<void()> CloudCallback;
class Cloud
{
private:
std::string url { "http://localhost:3000/1.0/" };
std::string end_point;
CloudCallback callback;
std::string getPath();
void onHttpRequestCompleted(HttpClient *sender, HttpResponse *response);
public:
Cloud (std::string end_point) : end_point(end_point) {}
void operator() (CloudCallback callback);
};
#endif /* Cloud_hpp */
これは、コンストラクタに渡されたコールバックを格納するクラスです。ここでは実装だ:私は何をしようとしている
#include "Cloud.hpp"
#include <iostream>
std::string Cloud::getPath()
{
return url + end_point;
}
void Cloud::operator()(CloudCallback callback)
{
this->callback = callback;
std::vector<std::string> headers;
HttpRequest* request = new (std::nothrow) HttpRequest();
request->setUrl(this->getPath().c_str());
request->setRequestType(HttpRequest::Type::GET);
request->setHeaders(headers);
request->setResponseCallback(CC_CALLBACK_2(Cloud::onHttpRequestCompleted, this));
HttpClient::getInstance()->send(request);
request->release();
}
void Cloud::onHttpRequestCompleted(HttpClient *sender, HttpResponse *response)
{
this->callback();
}
は次のように呼び出し、ファンクタの助けを借りて、簡単なHTTPリクエストを行い、次のとおりです。
Cloud cloud("decks");
cloud([&]() {
CCLOG("Got the decks");
});
私はEXC_BAD_ACCESS(コードを取得しています= EXC_I386_GPFLT)
this->callback();
と呼ばれます。
私はここで間違っていますか?
編集:今はスレッドと関係があると思います。 HttpRequestを削除してすぐにoperator()に渡されるコールバックメソッドを呼び出すと、問題なく動作します。
あなたのラムダキャプチャが参考になっていることに気付いています。つまり、ローカルスコープのものの参照に掛かることになります。コールバックが呼び出された時点でそれらが破棄されると、問題が発生します。また、ローカルの 'Cloud'オブジェクトを持っています - それはhttp要求よりも寿命が長くなっていますか?コールバックが呼び出される前にクラウドオブジェクトが破棄されるため、同じことが起こります。 –
httprequestが完了したら、Cloudオブジェクトが破棄されたと思います。メモリ管理はC++では難しい。 –
@AlexanderKondratskiyあなたは正しいです。スコープを変更すると問題が解決しました。あなたが答えとしてあなたのコメントを投稿できるなら、私はそれを受け入れることができます。 –