【问题标题】:Is there a way to create a static const class value that is initialized with a loop?有没有办法创建一个用循环初始化的静态 const 类值?
【发布时间】:2017-02-27 16:54:09
【问题描述】:

静态成员可以声明为 const,但必须在声明中对其进行初始化。考虑以下使用循环代码初始化静态数组的情况:

class A {
private:
  enum { SIZE = 360 };
  static double* vertices;
public:
  static void staticInit();
};

double* A::vertices = new double[SIZE];
void A::staticInit() {
  double a = 0, b = 0;
  for (int i = 0; i < SIZE; i++, a += .01, b += .02)
    vertices[i] = sin(a) + c2 * sin(b);
}

上面的代码可以工作。但如果目的是让顶点保持不变,那么将其声明为 const 将在 staticInit 函数上产生编译错误。

在较旧的 C++ 中,我会声明指针 const,并仅在此函数中将其转换为非 const,但今天,编译器不允许这样做,因为它不安全。当然,不声明指针 const 更不安全。

有什么干净的出路吗?

【问题讨论】:

    标签: c++11 static constants static-initialization


    【解决方案1】:

    创建一个返回std::arraymakeVertices 函数,然后通过调用它来初始化static 值:

    constexpr std::size_t size = 360;
    
    std::array<double, size> makeVertices()
    {
        std::array<double, size> vertices;
        double a = 0, b = 0;
    
        for (int i = 0; i < size; i++, a += .01, b += .02)
            vertices[i] = sin(a) + c2 * sin(b);
    
        return vertices;
    }
    

    makeVerticessize 都可以在 A 中定义。)

    class A {
    private:
      static std::array<double, size> vertices;
    };
    
    std::array<double, size> A::vertices = makeVertices();
    

    还要注意使用 constexpr 而不是 enum 来表示编译时数字常量 - 这是惯用的 C++11。

    【讨论】:

    • 谢谢,是的,仍然有“旧”的 C++ 反射
    【解决方案2】:

    我不明白为什么你不能把你关心的一切都变成 const 。为了简化用例:

    const T * const p = Init();
    
    T * Init()
    {
        T * result = new T[n];
        for (std::size_t i = 0; i != n; ++i)
          InitOne(result[i]);
        return result;
    }
    

    您应该能够将此方案应用于您的静态类成员。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 1970-01-01
      • 2018-01-13
      相关资源
      最近更新 更多