我有一組如下所示的類:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
};
class B {
public:
std::shared_ptr<C> c;
std::shared_ptr<C> getC() const {
return c;
}
void doSomethingWithSignalFromClassC() {}
};
class C {
public:
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
}
}
C::signalAsync()由 觸發A::triggerSignalCAsynchronously()。請注意,A::triggerSignalCAsynchronously()提交作品到佇列后立即回傳,但C::signalAsync()不會立即執行。一旦C::signalAsync()執行并完成其作業,它應該通知A::b::doSomethingWithSignalFromClassC().
我的問題是:如何通知B何時C::signalAsync()已經完成?從A,我們可以得到一個shared_pointer<C>。因此,自然的做法是存放weak_ptr<B>在里面C。但是,這不起作用,因為b它是唯一指標。我還考慮B在 C 內部存盤一個原始指標,但這似乎違背了unique_ptr設計。
此外,存盤指向Ain的原始指標C似乎很糟糕:
class A {
void setA() {
b->getC()->setA(this);
}
}
我覺得我的設計有問題。如果是你來解決這個問題,你會嘗試哪些方向?
uj5u.com熱心網友回復:
你需要對你的要求非常精確。你說
一旦 C::signalAsync() 被執行并完成它的作業,它應該通知 A::b::doSomethingWithSignalFromClassC()
“通知”意味著一個執行緒正在某處等待被喚醒以做某事 - 這很復雜
但你也可以說,我希望 singalAsync 呼叫 B 實體上的方法。這很簡單。
不知道這些呼叫的約束(你不會全部或者是一些你不能改變的庫等)使它更難。
這是我將為回呼案例做的事情
class C {
std::shared_ptr<B> callback_;
public:
C(std::shared_ptr<B> &cb){
callback_ = cb;
}
void signalAsync() {
// noodle noodle noodle
callback_->doSomethingWithSignalFromClassC();
}
}
即,當我構造一個 C 物件時,告訴它要回呼的物件。
或者,您可以將其作為 arg 傳遞給 signalAsync 但也許那是不可能的
另一個想法是std::function在建構式中傳遞 a ,這樣您就不必硬編碼在 signalAsync 結束時呼叫的方法
uj5u.com熱心網友回復:
根據 pm100's answer,std::function實際的用法是有效的。我想寫下我最后做了什么,以防萬一有人需要。更多細節,在我的例子中,C的頭檔案不能包含B的頭檔案,因為B已經包含C在它的頭檔案中(前向宣告不起作用)。C也不能包括A因為A被設計成一個實作類(Pointer to Implementation idiom);因此,A標題位于src檔案夾內,不應包含在任何地方(除了A.cc)
我最后做了什么:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
void setFunctionToC() {
// This happens before triggerAsynchronously()
auto do_something_when_finished = [&b = b]() {
b->doSomethingWithSignalFromClassC();
}
b->getC()->setFunctionToC(do_something_when_finished);
}
};
class C {
std::function<void()> call_on_finished;
public:
void setFunctionToC(std::function<void()> f) {
call_on_finished = f;
}
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
call_on_finished();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/453710.html
下一篇:如何在NodeJS中等待函式執行
