初始化后修改静态成员

Modifying Static Member after Initialization

本文关键字:静态成员 修改 初始化      更新时间:2023-10-16

我遇到了一个奇怪的问题,初始化类后我无法修改类的静态成员之一。这是我的代码:

my_values.hpp

#include "weird_class.hpp"
namespace foo {
class Bar {
 public:
  static WeirdClass weird_class_obj;
};

my_values.cpp

#include "weird_class.hpp"
#include "my_values.hpp"
namespace foo {
  WeirdClass Bar::weird_class_obj = WeirdClass(1.0f, 0.0f, 1.0f, 100.0f);
  Bar::weird_class_obj.set_weird_value(100.0f);
}

weird_class.hpp

#ifndef WEIRD_CLASS_H
#define WEIRD_CLASS_H
class WeirdClass {
public:
 WeirdClass(float, float, float, float);
 void set_weird_value(float);
private:
 float weird_value;
};
#endif

weird_class.cpp

#include "weird_class.hpp"
void WeirdClass::set_weird_value(float weirdValue) {
  weird_value = weirdValue;    
}

如果我注释掉 5 行my_values.cpp文件编译正常。但如果我不这样做,我得到的错误是

error: no type named 'weird_class_obj' in 'foo::Bar' Bar::weird_class_obj.set_weird_value(100.0f);
                                                          ^
error: cannot use dot operator on a type Bar::weird_class_obj.set_weird_value(100.0f);
                                                             ^

我的猜测是,weird_class_obj以某种方式被视为一种类型,而不是类WeirdClass的对象。但为什么会这样呢?

问题不在于您不能修改对象。问题是你放置了这个:

Bar::weird_class_obj.set_weird_value(100.0f);

一个可执行语句,进入命名空间范围。这是不允许的。

如果 WeirdClass 的 c'tor 很奇怪,以至于您可能不会在其中设置值,但该类并没有奇怪到不允许复制/移动,您可以使用以下技巧:

WeirdClass Bar::weird_class_obj = []() {
  WeirdClass obj(1.0f, 0.0f, 1.0f, 100.0f);
  obj.set_weird_value(100.0f);
  return obj;
}();

以上在 JavaScript 世界中被称为 IIFE。如果您由于某种原因无法做到这一点,那么命名的 free 函数也可以用于相同的目的。