Tôi gặp sự cố khi tôi phải khởi tạo phiên bản đối tượng sớm hơn tôi muốn làm như vậy vì tôi cần kết nối tín hiệu vị trí thông qua một số quyền sở hữu sâu và tôi muốn tìm ra cách lưu trữ và chuyển tiếp các vị trí để tôi có thể xây dựng các đối tượng gần hơn đến trang web sử dụng của chúng, thay vì làm như vậy dưới dạng biến thành viên.Làm cách nào để lưu trữ và chuyển tiếp các vị trí bằng cách sử dụng tăng :: signal2?
Vấn đề cơ bản của tôi là tôi có một quá trình sẽ tải xuống bản cập nhật tệp trên một chuỗi riêng biệt và gửi tín hiệu tiến độ cho bất kỳ ai là quan tâm. Các tín hiệu về cơ bản là:
typedef boost::signals2::signal<void (double)> DownloadProgress;
Giả định rằng việc thực hiện các chức năng progress
nêu dưới đây phù hợp với này; bản chất của tín hiệu chính nó không phải là rất quan trọng (mặc dù tôi đang sử dụng functors cho hầu hết các phần).
Các tín hiệu được thiết lập và mã được gọi là một cái gì đó như thế này:
Updater updater;
updater.onDownloadProgress(&progress);
updater.runDownloadTask();
Khi bạn gọi updater.runDownloadTask()
, nó sẽ bắt đầu UpdaterDownloadTask
, bắt đầu một HTTPRequest
và trả về một HTTPResponse
. HTTPResponse
là phần tương tác với lớp mạng và nhận dữ liệu và chứa tín hiệu DownloadProgress
. Với điều này, thực hiện của tôi trông hơi giống (từ dưới lên từ HTTPResponse
, nặng nề viết tắt là bõ mẫu âm chót phương pháp mà không phải là đặc biệt là minh họa):
class HTTPResponse
{
public:
// this will be called for every "chunk" the underlying HTTP
// library receives
void processData(const char* data, size_t size)
{
// process the data and then send the progress signal
// assume that currentSize_ and totalSize_ are properly set
progressSignal_(currentSize_ * 100.0/totalSize_);
}
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
progressSignal_.connect(slot);
}
private:
DownloadProgress progressSignal_;
};
class HTTPRequest
{
public:
HTTPRequest() : response_(new HTTPResponse) { }
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
response_->connect(slot);
}
boost::shared_ptr<HTTPResponse> perform()
{
// start the request, which operates on response_.
return response_;
}
private:
boost::shared_ptr<HTTPResponse> response_;
};
class UpdaterDownloadTask : public AsyncTask
{
public:
DownloadTask() : request_(new HTTPRequest) { }
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
request_->connect(slot);
}
void run()
{
// set up the request_ and:
request_>perform();
}
private:
boost::shared_ptr<HTTPRequest> request_;
};
class Updater
{
public:
Updater() : downloadTask_(new UpdaterDownloadTask) { }
void onDownloadProgress(const DownloadProgress::slot_type& slot)
{
downloadTask_->onDownloadProgress(slot);
}
void runDownloadTask() { downloadTask_.submit() }
private:
boost::shared_ptr<UpdaterDownloadTask> downloadTask_;
};
Vì vậy, Updater tôi phải có một thể hiện của UpdaterDownloadTask
đó là luôn xung quanh, trong đó có một thể hiện của HTTPRequest
, trong đó có một trường hợp của HTTPResponse
-Cũng vì tôi phải chuyển khe kết nối từ Updater
(API công cộng entry point) để HTTPResponse
(nơi các tín hiệu thuộc).
Tôi thà thực hiện UpdaterDownloadTask::run()
như vậy:
void run()
{
HTTPRequest request;
request.onDownloadProgress(slots_);
#if 0
// The above is more or less equivalent to
BOOST_FOREACH(const DownloadProgress::slot_type& slot, slots_)
{
request.onDownloadProgress(slot);
}
#endif
request.perform();
}
Điều này sẽ có tác động tương tự ở cấp HttpRequest (vì vậy tôi không cần phải xây dựng các HttpResponse cho đến khi tôi thực hiện theo yêu cầu) và làm cho tổng thể cho một luồng dữ liệu đẹp hơn với ngữ nghĩa RAII mạnh mẽ. Tôi đã trước đó cố gắng xác định các biến slots_
như một vector:
std::vector<DownloadProgress::slot_type> slots_;
Tuy nhiên, tôi chỉ có thể có được điều này để làm việc nếu tôi buộc người gọi phải gọi onDownloadProgress(boost::ref(slot));
.
Có ai đã làm điều này thành công hay có đề xuất tốt về cách lưu trữ và chuyển tiếp khác với những gì tôi đang làm không?
Tôi đã thử một số thứ với một véc tơ trước đó, nhưng có thể do lỗi của tôi. Tôi nghĩ bạn đúng. –