我有一個不斷流的bool值。當布爾變爲true時,我需要觸發一個函數,另一個布爾變爲false時,但每次更改只有一次,所以我不能使用while(true)
循環。bool更改時的C++觸發函數
什麼是最好的方式在c + +「觀察」一個值,並在它發生變化時觸發?
謝謝。
我有一個不斷流的bool值。當布爾變爲true時,我需要觸發一個函數,另一個布爾變爲false時,但每次更改只有一次,所以我不能使用while(true)
循環。bool更改時的C++觸發函數
什麼是最好的方式在c + +「觀察」一個值,並在它發生變化時觸發?
謝謝。
我會去設置一個flagTrue變量和一個flagFalse變量。當您遇到第一個True時,flagTrue從false更改爲true,並且所有跟隨True的布爾值都將被忽略。同樣,當你遇到你的錯誤False時,flagFalse會從False變爲True,並忽略所有跟隨的False布爾值。另外,當被檢查的布爾值從True更改爲False時,將會將flagTrue更改爲False,並且在另一種情況下也會類似。
例子:
flagTrue = false
flagFalse = false
if (bool == true && flagTrue == false)
{
// DoSomething
flagTrue = true;
flagFalse = false;
}
else if (bool == false && flagFalse == false)
{
// DoSomething
flagTrue = false;
flagFalse = true;
}
看看Observer模式。你可以將你的布爾值封裝在一個助手類中,當布爾值被設置時觸發一個事件。
實施例實現可觀察到的布爾的:
#include <vector>
class Observer {
public:
virtual void valueChanged() = 0;
};
class ObservableBool {
private:
bool value;
std::vector<Observer*> observers = std::vector<Observer*>();
public:
bool getValue() {
return value;
}
bool setValue(bool value) {
bool changed = (value != this->value);
this->value = value;
if(changed) raiseEvent();
}
void addObserver(Observer* observer) {
observers.push_back(observer);
}
void removeObserver(Observer* observer) {
observers.erase(std::find(observers.begin, observers.end, observer));
}
private:
void raiseEvent() {
for (int i = 0; i < observers.size; ++i) {
observers[i]->valueChanged();
}
}
};
這可以提高了很多。一個非常好的方法是實現從bool到bool的隱式轉換(但要小心,爲bool設置'='運算符會很危險)。你可以模板它來支持任意類型,而不僅僅是布爾,你應該使用智能指針而不是原始指針(std::weak_ptr
將是最好的),而不是Observer類,你應該使用函數指針來正確支持lambdas。如果你做得對,你可以像普通的布爾值一樣使用這個類,當設置一個新的值時,會有小的開銷。默認情況下,所有對更改的反應都是由更改值的線程執行的。
我可能會開始像這樣:
#include <functional>
#include <atomic>
#include <iostream>
struct trigger
{
using closure_type = std::function<void()>;
trigger(closure_type on_set, closure_type on_reset, bool initial_state = false)
: _state { initial_state }
, _on_set(std::move(on_set))
, _on_reset(std::move(on_reset))
{}
void set() {
if (not _state.exchange(true)) {
_on_set();
}
}
void reset() {
if (_state.exchange(false)) {
_on_reset();
}
}
std::atomic<bool> _state;
std::function<void()> _on_set;
std::function<void()> _on_reset;
};
void has_set() {
// you can marshall accross threads here by posting calls to a
// queue
std::cout << __func__ << std::endl;
}
void has_unset() {
// you can marshall accross threads here by posting calls to a
// queue
std::cout << __func__ << std::endl;
}
int main()
{
trigger t { has_set, has_unset };
t.set();
t.set();
t.reset();
t.reset();
}
查找爲['的std :: condition_variable'(http://en.cppreference.com/w/cpp/thread/condition_variable) –