gpt4 book ai didi

C++ static const 和初始化(有没有惨败)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:17:46 24 4
gpt4 key购买 nike

我在久违后重返 C++,我对众所周知的静态初始化问题的理解有些磕磕绊绊。

假设我有一个简单的类 Vector2,如下所示(请注意,我知道 x 和 y 应该与 getter 和 setter 私有(private),为简洁起见,这些只是被省略了):

class Vector2 {

public:
Vector2(float x, float y) :x(x), y(y) {};
float x,y;
}

现在,如果我想指定一个静态常量成员来表示 x 和 y 设置为 1 的 Vector2,我不确定如何进行——静态常量成员是否会陷入静态初始化问题或让他们 const 意味着他们还好吗?我正在考虑以下可能性:

可能性一:

// .h
class Vector2 {

public:
Vector2(float x, float y) :x(x), y(y) {}
static const Vector2 ONE;
float x,y;
};

// .cpp
const Vector2 Vector2::ONE = Vector2(1.f, 1.f);

可能性2:

// .h
class Vector2 {

public:
Vector2(float x, float y) :x(x), y(y) {}
static const Vector2& getOne();
float x,y;
private:
static const Vector2 ONE;
};

// .cpp
const Vector2 Vector2::ONE = Vector2(1.f, 1.f);

static const Vector2& Vector2::getOne() {
return ONE;
}

可能性三:

// .h
class Vector2 {

public:
Vector2(float x, float y) :x(x), y(y) {}
static const Vector2& getOne();
float x,y;
};

// .cpp
const Vector2& Vector2::getOne() {
static Vector2 one(1.f,1.f);
return one;
}

现在,我更喜欢用第二种方式来编写它,因为它对我来说是一种更舒适的语法。但是,如果我从另一个类中的另一个静态方法调用 getOne() 方法,我是否会面临崩溃和燃烧的风险?正如我所说,这是因为我使用的是静态 const 而不是普通静态,所以我问这个问题,因为我在普通静态类成员问题上发现了很多,但在 const static 问题上却一无所获。

我怀疑我使用的是 static const 并且需要使用可能性 3 以确保安全,这一事实让我一无所获,但我只是想问一下,以防有人能为我阐明这一点。

我意识到我可能会打开大量指向我所问内容的链接,但在发布此之前我已经看过但没有找到。

如有任何帮助,我们将不胜感激。

最佳答案

除了可能性 3 之外,所有这些都遭受了静态初始化顺序的失败。这是因为您的类(class)不是 POD。在C++0x中,这个问题可以通过标记构造函数constexpr来解决,但是在C++03中没有这样的解决方法。

在C++03中可以去掉构造函数解决问题,使用初始化

const Vector2 Vector2::ONE = { 1.f, 1.f };

这是在初始化一个POD,列表中的所有初始化器都是常量表达式(用于静态初始化)。它们的初始化发生在运行任何可能在初始化之前访问它的代码之前。

3.6.2:

Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place. Zero-initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place.

8.5.1/14:

When an aggregate with static storage duration is initialized with a brace-enclosed initializer-list, if all the member initializer expressions are constant expressions, and the aggregate is a POD type, the initialization shall be done during the static phase of initialization (3.6.2); otherwise, it is unspecified whether the initialization of members with constant expressions takes place during the static phase or during the dynamic phase of initialization.

关于C++ static const 和初始化(有没有惨败),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2373859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com