【问题标题】:How to declare static variable in a class method that is not shared between all instances of a class?如何在类的所有实例之间不共享的类方法中声明静态变量?
【发布时间】:2021-08-24 23:19:56
【问题描述】:

我希望以下代码创建 2 个不同的 i 变量或每个实例一个。

class A {
   void foo() {
      static int i = 0;
      i++;
      std::cout << i << std::endl;
   }
}

auto i1 = A();
auto i2 = A();

i1.foo();
i2.foo();

我希望输出是:

0
0

如何声明一个仅存在于该函数中但在函数调用之间保持不变的变量?

如果您对我需要这种行为的确切原因感到好奇,我认为这个问题有点复杂并且没有必要,但这是我正在处理的问题:

我正在尝试创建一个用于日志记录的宏,它创建一个限制日志记录输出的静态 lambda。它旨在用于类方法中。当前的宏如下所示。

#define ROS_UTILS_THROTTLE_MACRO(LOG_MACRO, message, duration) do {                                         \
  static auto COMBINE(throttle_log_,__LINE__) = [&](const std::string&& msg, rclcpp::Duration&& period) {   \
    static auto next_log_time = ros2_utils::system_time_now() + period;                                     \
    auto current_time = ros2_utils::system_time_now();                                                      \
    if(current_time >= next_log_time)                                                                       \
    {                                                                                                       \
        LOG_MACRO(message);                                                                                 \
        next_log_time += period;                                                                            \
        if(next_log_time <= current_time)                                                                   \
        {                                                                                                   \
            next_log_time += period;                                                                        \
        }                                                                                                   \
    }                                                                                                       \
  };                                                                                                        \
  COMBINE(throttle_log_,__LINE__)(message, duration);                                                       \
} while (0)

这个宏的用法(大致)如下所示:

class A {
   void foo() {
      ROS_UTILS_THROTTLE_MACRO(INFO_LOG, "message", 1s);
   }
}

A 的 2 个实例应该有 2 个不同的日志函数,它们都分别受到限制。

【问题讨论】:

  • 使用类成员变量?
  • 不能让它成为A的成员吗?这将为每个实例提供一个,但显然它将在A 的所有函数之间共享。但通常有一个类的成员只在几个函数中使用
  • 我无法将其添加为成员变量,因为我正在尝试编写一个用于在函数中创建变量的日志记录宏。我需要该变量在函数调用之间保持不变,以便日志记录按预期工作。宏声明的变量是一个 lambda,它跟踪上次记录的时间并确保上次记录的时间不在限制持续时间内。
  • 您不能拥有特定于实例的 static 变量。看来您正面临XY Problem
  • @Slava 在__func__ 上键入地图不会产生每个实例的值,但

标签: c++ class static


【解决方案1】:

查看您的宏代码,我认为以下想法应该可行。

class A {
   void foo() {
      static std::map<A*, int> theMap; // This is the logging specific
                                       // data, unrelated to the data
                                       // of the class.
      theMap[this]++;
      std::cout << theMap[this] << std::endl;
   }
};

该方法的一个缺点是,在程序退出之前,您将无法释放theMap 使用的内存。如果您构造和销毁大量A 的实例,您会注意到内存使用量上升,而无法释放与删除对象对应的内存。

感谢@RemyLebeau 指出这一点。

【讨论】:

  • 这种方法会随着时间的推移泄漏map 条目,因为在调用foo() 之后销毁this 时,无法删除每个A* 键。您必须将map 声明为类静态或全局变量,以便~A() 析构函数可以访问它
  • @RemyLebeau,完全同意。我认为类静态变量对于 OP 来说是不可能的,因为他们希望它是特定于功能的。
  • 如果类需要为每个方法单独的每个实例计数器,它可以简单地为每个要访问的方法声明一个单独的类静态 map 成员,同时仍然允许析构函数删除 this来自所有maps。这确实是使用this 作为map 键时避免内存泄漏的唯一方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
相关资源
最近更新 更多