【问题标题】:Objects vs. Static Variables for retaining function state用于保留功能状态的对象与静态变量
【发布时间】:2021-04-15 13:06:25
【问题描述】:

我有一个函数可以处理以序列形式出现的数据。因此,我需要知道当前函数调用期间最后一次函数调用的某些变量的值。

我目前的做法是使用静态变量。我的功能是这样的:

bool processData(Object message){
    static int lastVar1 = -1;

    int curVar1 = message.var1;
    if (curVar1 > lastVar1){
        // Do something
    }

    lastVar1 = curVar1;
}

这只是一小部分代码;实际上,我有 10 多个静态变量跟踪不同的事物。我的直觉告诉我使用这么多静态变量可能不是一个好主意,尽管我没有什么可以支持这种感觉。

我的问题:有没有更好的方法来做到这一点?

我一直在研究的另一种方法是使用字段为 lastVar1、lastVar2 等的对象。但是,我不确定将对象保存在内存中是否比使用静态变量更有效。

【问题讨论】:

  • 除了当前对象之外,您不需要具有名为lastVar1lastVar2 等成员的对象。您需要一个包含成员Var1Var2 等的类以及两个对象currentprevious,如果该方法同时需要这两个对象,则调用者应该同时传递它们,而不是将其埋在函数中,使其基本上无法测试
  • 带有成员的对象将更容易测试,并允许从多个上下文调用方法(静态重入问题,...)。
  • 静态局部变量使函数不可重入,如果您想在多个线程中运行代码,这可能很重要。
  • 这个函数应该是一个类方法,并且这个类方法应该有一个私有的类成员,用于这个目的。毕竟,这就是 C++ 的用途:类。
  • 可变静态几乎从来都不是正确的答案;支撑一个设计通常是一根拐杖——但具有讽刺意味的是,它经常削弱它。 static state 会使单元测试变得困难,因为 state 可能会在测试之间转移,难以创建多个实例(因为它们现在隐式共享 state),不可重入等。你最好使用结构化设计记录previouscurrent 状态——如果不是为了你自己的理智,那么至少为了任何未来维护者的理智

标签: c++ object static


【解决方案1】:

您的问题有点纯粹是关于风格和意见,尽管有些方面不是意见问题:多线程和测试。

考虑一下:

bool foo(int x) {
    static last_val = -1;
    bool result = (x == last_val);
    last_val = x;
    return result;
}

您可以从多个线程同时调用此函数,但它不会达到预期的效果。此外,您只能通过断言它做正确的事情来测试该函数:

   foo(1);
   assert( foo(1) );    // silenty assumes that the last call did the right thing

要设置测试的先决条件(第一行),您必须假设 foo(1) 做了正确的事情,这在某种程度上违背了在第二行中测试调用的目的。

如果方法需要当前对象和前一个对象,只需传递两者:

bool processData(const Object& message,const Object& previous_message){

    if (message.var1 > previous_message.var1){
        // Do something
        return true;
    }   
    return false;
}

当然,这只是将跟踪上一条消息的问题转移给调用者,尽管这是直截了当的并且不需要搞乱静态:

 Object message, old_message;
 while ( get_more( message )) {
     processData(message, old_message);
     old_message = message;
 }

【讨论】:

  • 不幸的是,我的代码可能过于简化了。我不简单地传入 old_message 的原因是,为了获得 curVar1 和其他的值,必须进行大量的处理。如果我要传入 old_message,则必须进行两次处理
  • @Star-lordX 不,您不必执行两次,您执行一次并将其两次传递给方法。答案只是略有变化,签名是bool processData(Object message, Preprocessed current, Preprocessed previous)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 2012-08-23
相关资源
最近更新 更多