微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C静态const和初始化(有惨败)

我很久没有回到C了,而且我对这个众所周知的静态初始化问题的理解有点磕磕绊绊.

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

class Vector2 {

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

现在,如果我想指定一个静态const成员来表示一个x和y设置为1的Vector2,我不确定如何继续 – 静态const成员会违反静态初始化问题,还是会使它们成为const的行为他们还好吗?我正在玩弄以下可能性:

可能性1:

// .h
class Vector2 {

public:
  Vector2(float 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,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;
}

可能性3:

// .h
class Vector2 {

public:
  Vector2(float x,y;
};

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

现在,我写这篇文章的首选方式与可能性2一样,只是因为它对我来说是一种更舒适的语法.但是,如果我从另一个类中的另一个静态方法调用getone()方法,我将冒险崩溃和刻录?正如我所说,这是因为我使用静态const而不是普通的静态我问这个问题,因为我在普通的静态类成员问题上发现了很多,但在静态问题上却没有.

我怀疑我没有得到任何东西,因为我使用静态const并且需要使用Possibility 3才能安全,但我只是想问一下,以防万一有人可以为我阐明这一点.

我意识到我可能会打开一大堆链接,指向我正在询问的内容,但是在发布之前我已经看过并且没有找到.

任何帮助将不胜感激.

解决方法

除了可能性3之外,所有这些都受到静态初始化顺序惨败的影响.这是因为你的班级不是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.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐