C++ 使用C+中的方法更新外部结构+;

C++ 使用C+中的方法更新外部结构+;,c++,C++,我目前正在使用automatak的opendnp3包 我无法理解的是如何在不将结构传递给类的情况下更新结构(定义在类的范围之外)中的信息(我认为我做不到这一点,因为我的代码从未实际调用该方法,所以在调用该方法时我无法更改传递给该方法的内容) 继承关系图: 我通过创建自己的类(myCommand Handler)覆盖了SimpleCommand Handler类中的虚拟方法DoOperate。从DoOperate功能返回的任何东西都由asio供电 struct State { doubl

我目前正在使用automatak的opendnp3包

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

继承关系图:

我通过创建自己的类(myCommand Handler)覆盖了SimpleCommand Handler类中的虚拟方法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状态
{
双值0=0;
双值1=0;
bool binary0=false;
bool binary1=false;
};
国家;
类myCommand Handler:公共SimpleCommand Handler
{
公众:
静态std::shared_ptr Create()
{
返回std::make_shared();
}
MyCommand Handler():SimpleCommand Handler(CommandStatus::SUCCESS){}
受保护的:
void DoOperate(const controlrelayoutblock&command,uint16_t index,OperateType opType){
////***这就是我需要更新结构的地方***////
////state.value0=30////
////state.value1=30////
////state.binary0=true////
////state.binary1=true;///
}
}
};
我能想到的唯一方法是使结构全局化,但从我在这里读到的内容来看,这似乎是糟糕的编码实践

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

我已经为这个问题挣扎了一段时间,所以任何帮助都将不胜感激


谢谢

全局对象的问题之一是初始化或销毁顺序可能会出现问题。因此,理论上,
DoOperate
可能在
状态
尚未初始化或已销毁时调用(当应用程序退出时可能会调用)

但是,即使您的应用程序可能不是这样,您仍然希望通过设计使if安全

对于您的
MyCommandHandler
来说,调用
DoOperate
时它应该不重要,因此
MyCommandHandler
对象需要在其整个活动时间内拥有
状态,或者,如果只有在调用
DoOperate
时才需要它,则应将其作为参数传递给
DoOperate

如果您将其作为参数传递给
DoOperate
,那么调用该操作符的对象应该在其整个生命周期内拥有state对象,或者应该将其作为参数传递给调用
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_;
};

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

将对象的引用或智能指针作为类成员保留?如果整个程序中只有一个状态,则可以使用单例模式,而不是全局变量。但是@NathanOliver有imho最佳解决方案。@NathanOliver提出了一种pimpl习语形式,您可能想查阅一下。
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 = ...
    }
};