有没有办法创建一个用循环初始化的 static const class 值?
Is there a way to create a static const class value that is initialized with a loop?
静态成员可以声明为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);
}
上面的代码可以工作。但是如果目的是使顶点常量,那么将其声明为常量将在 staticInit 函数上产生编译错误。
在旧的 C++ 中,我会声明指针 const,并仅在此函数中将其转换为非常量,但今天,编译器不允许这样做,因为它不安全。当然,不声明指针const更不安全。
有什么干净的出路吗?
创建一个 makeVertices
函数 returns 一个 std::array
,然后通过调用它来初始化 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;
}
(makeVertices
和size
都可以定义在A
里面。)
class A {
private:
static std::array<double, size> vertices;
};
std::array<double, size> A::vertices = makeVertices();
还要注意使用 constexpr
而不是 enum
来表示编译时数值常量——这是 C++11 的惯用做法。
我不明白为什么你不能把你关心的一切都变成常量。简化用例:
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;
}
您应该能够将此方案应用于您的静态 class 成员。
静态成员可以声明为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);
}
上面的代码可以工作。但是如果目的是使顶点常量,那么将其声明为常量将在 staticInit 函数上产生编译错误。
在旧的 C++ 中,我会声明指针 const,并仅在此函数中将其转换为非常量,但今天,编译器不允许这样做,因为它不安全。当然,不声明指针const更不安全。
有什么干净的出路吗?
创建一个 makeVertices
函数 returns 一个 std::array
,然后通过调用它来初始化 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;
}
(makeVertices
和size
都可以定义在A
里面。)
class A {
private:
static std::array<double, size> vertices;
};
std::array<double, size> A::vertices = makeVertices();
还要注意使用 constexpr
而不是 enum
来表示编译时数值常量——这是 C++11 的惯用做法。
我不明白为什么你不能把你关心的一切都变成常量。简化用例:
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;
}
您应该能够将此方案应用于您的静态 class 成员。