gpt4 book ai didi

c++ - 在 C++ 中使用方法更新外部结构

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:39:21 25 4
gpt4 key购买 nike

我目前正在使用 automatak 的 opendnp3 包。 https://github.com/automatak/dnp3/blob/2.0.x/cpp/examples/outstation/main.cpp .

我无法理解的是如何在不将结构传递到类中的情况下更新结构(定义在类范围之外)中的信息(我认为我不能像我的代码那样做)从未实际调用该方法,因此我无法更改调用时传递给该方法的内容。

继承图:

我通过创建自己的类 (MyCommandHandler) 覆盖了 SimpleCommandHandler 类中的虚方法 DoOperate。 DoOperate 函数返回的任何内容均由 asio 提供支持。

struct State
{
double value0 = 0;
double value1 = 0;
bool binary0 = false;
bool binary1 = false;

};

State state;

class MyCommandHandler : public SimpleCommandHandler
{
public:

static std::shared_ptr<ICommandHandler> Create()
{
return std::make_shared<MyCommandHandler>();
}

MyCommandHandler() : SimpleCommandHandler(CommandStatus::SUCCESS) {}

protected:

void DoOperate(const ControlRelayOutputBlock& command, uint16_t index, OperateType opType) {

////*** This is where I need to update the Struct ***////
//// state.value0 = 30; ////
//// state.value1 = 30; ////
//// state.binary0 = true; ////
//// state.binary1 = true; ////
}

}
};

我能想到的唯一方法是使 Struct 全局化,但从我在这里阅读的内容来看,这似乎是糟糕的编码实践 Making Global Struct in C++ Program .

简而言之,我想知道 - 使用由某些外部事件触发的方法 (DoOperate) 修改类外部数据(结构)的最佳实践是什么?

我已经为此苦苦挣扎了一段时间,所以非常感谢任何帮助。

谢谢!!

最佳答案

全局对象的一个​​问题是您可能会遇到初始化或销毁顺序方面的问题。因此理论上 DoOperate 可能会在 State state 尚未初始化或已被破坏时调用(这可能在应用程序退出时避风港)。

但即使您的应用程序可能不是这种情况,您仍然希望通过设计确保安全。

对于您的 MyCommandHandler,何时调用 DoOperate 应该不重要,因此 MyCommandHandler 对象需要拥有 状态 在其整个生命周期内,或者如果仅在调用 DoOperate 时才需要它,则您应该将其作为参数传递给 DoOperate

如果您将它作为参数传递给 DoOperate,那么调用该运算符的对象应该在其整个生命周期内拥有状态对象,或者应该将它作为调用 DoOperate 的函数的参数。 ...

如果你真的想使用全局状态对象,那么你可以这样做:

std::shared_ptr<State> get_global_state() {
static std::shared_ptr<State> state = std::make_shared<State>();

return state;
}


class MyCommandHandler : public SimpleCommandHandler
{
public:
MyCommandHandler() : state_(get_global_state()) {}

static std::shared_ptr<ICommandHandler> Create()
{
return std::make_shared<MyCommandHandler>();
}

MyCommandHandler() : SimpleCommandHandler(CommandStatus::SUCCESS) {}

void DoOperate(const ControlRelayOutputBlock& command, uint16_t index, OperateType opType) {
// state_-> value0 = ...
}

protected:
std::shared_ptr<State> state_;
};

或者像这样的代码,如果你将它作为参数传递给 DoOperate

struct HandlerCaller {
void call_handlers() {
for( auto &handler : handlers ) {
handler->DoOperate(state_.get(), /*...*/ )
}
}

std::shared_ptr<State> state_;
}


class MyCommandHandler : public SimpleCommandHandler
{
void DoOperate(State * const state, const ControlRelayOutputBlock& command, uint16_t index, OperateType opType) {
// state-> value0 = ...
}
};

我个人不喜欢单例,但重要的是这里的所有权。

关于c++ - 在 C++ 中使用方法更新外部结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54889861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com