C++无状态类的静态初始化

发布于 2024-11-07 11:12:39 字数 866 浏览 2 评论 0 原文

假设我有一个类 T,其中

  1. T 没有虚函数。
  2. T 实例没有状态。
  3. T 具有其自身的静态成员实例。
  4. T本身没有其他状态。

C++ 静态初始化失败会毁掉我的程序吗?我不这么认为,因为即使其中一个静态实例在使用前未初始化,那也没关系,因为 T 对象是无状态的。

我有兴趣为类似枚举的类执行此操作,如下所示:


// Switch.h

class Switch {
public:
    static Switch const ON;
    static Switch const OFF;
    bool operator== (Switch const &s) const;
    bool operator!= (Switch const &s) const;
private:
    Switch () {}
    Switch (Switch const &); // no implementation
    Switch & operator= (Switch const &); // no implementation
};

// Switch.cpp

Switch const Switch::ON;
Switch const Switch::OFF;

bool Switch::operator== (Switch const &s) const {
    return this == &s;
}

bool Switch::operator!= (Switch const &s) const {
    return this != &s;
}

Suppose I have a class T where

  1. T has no virtual functions.
  2. T instances have no state.
  3. T has static member instances of itself.
  4. T itself has no other state.

Can the C++ static initialization fiasco ruin my program? I don't think so because even if one of the static instances is not initialized before use, that should not matter because T objects are stateless.

I'm interested in doing this for enum-like classes like so:


// Switch.h

class Switch {
public:
    static Switch const ON;
    static Switch const OFF;
    bool operator== (Switch const &s) const;
    bool operator!= (Switch const &s) const;
private:
    Switch () {}
    Switch (Switch const &); // no implementation
    Switch & operator= (Switch const &); // no implementation
};

// Switch.cpp

Switch const Switch::ON;
Switch const Switch::OFF;

bool Switch::operator== (Switch const &s) const {
    return this == &s;
}

bool Switch::operator!= (Switch const &s) const {
    return this != &s;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰雪梦之恋 2024-11-14 11:12:39

为了回答你的问题的第一部分,如果 T 有一个有副作用的构造函数,那么你实际上可能会被静态初始化惨败所烧毁。

To answer the first part of your question, if T has a constructor which has side effects then you can in fact get burned by static initialization fiasco.

白云悠悠 2024-11-14 11:12:39

我感兴趣的是,您从包装在名称空间或类中的枚举中看到的优点是什么:

namespace Switch {
   enum Switch {
      ON,
      OFF
   };
}

在大多数情况下使用起来会更简单(在您的实现中,您要求用户使用引用或指针,如对象是不可复制的),它需要更少的代码(不需要禁用构造函数,并创建运算符)...

事实上,在即将推出的标准中,您几乎可以免费获得它,甚至不需要使用命名空间:

enum Switch {
   ON,
   OFF
};
// bad, it allows this (as in the current standard):
Switch s = ON;
// good, it does also allow explicit qualification:
Switch s = Switch::ON;

I am interested in what are the advantages that you see from, say, an enum wrapped in either a namespace or a class:

namespace Switch {
   enum Switch {
      ON,
      OFF
   };
}

It will be simpler to use in most cases (in your implementation you require users to employ either references or pointers, as the objects are non-copyable), it requires less code (no need to disable the constructors, and create the operators)...

As a matter of fact, in the upcoming standard you almost get that for free without even the use of the namespace:

enum Switch {
   ON,
   OFF
};
// bad, it allows this (as in the current standard):
Switch s = ON;
// good, it does also allow explicit qualification:
Switch s = Switch::ON;
回首观望 2024-11-14 11:12:39

您真的打算使用指针值来比较“状态”吗?我同意@Drew,这是一个有趣的想法。不过,如果我们假设这是一个仅包含标头的实现,我不确定标准是否能保证它正常工作。

考虑一下当多个编译对象包含相同的 Switch::ONSwitch::OFF 定义时会发生什么情况。由于这些是变量,而不是函数,因此链接器必须在它们之间任意做出决定。

当您运行测试时,流行的编译器会说什么:gcc 3、gcc 4、microsoft C++ 2005、2008 和 2010,以及 Edison Design Groups 的编译器之一,例如 http://www.comeaucomputing.com/ ?

测试将包括:

// Switch.h
class Switch {
public:
    static Switch const ON;
    static Switch const OFF;
    bool operator== (Switch const &s) const;
    bool operator!= (Switch const &s) const;
private:
    Switch () {}
    Switch (Switch const &); // no implementation
    Switch & operator= (Switch const &); // no implementation
};

Switch const Switch::ON;
Switch const Switch::OFF;

bool Switch::operator== (Switch const &s) const {
    return this == &s;
}

bool Switch::operator!= (Switch const &s) const {
    return this != &s;
}

// main.cpp
#include "Switch.h"

extern int another_test();

int main(int argc, char*argv[])
{
  another_test();
  const Switch& current_state = Switch::ON;
  const Switch& another_state = Switch::OFF;
  if (current_state == another_state) {
    return 1;
  } else if (current_state != another_state) {
    return 2;
  }
  return another_test();
}

所述

// another_test.cpp
#include "Switch.h"

int another_test()
{
  const Switch& current_state = Switch::ON;
  const Switch& another_state = Switch::OFF;
  if (current_state == another_state) {
    return 4;
  } else if (current_state != another_state) {
    return 5;
  }
  return 6;
}

Do you really intend to use pointer values to compare "state"? I agree with @Drew, it's an interesting idea. I'm not sure it is guaranteed by the standard to work, though, if we assume that this is a header-only implementation.

Consider what happens when multiple compilation objects contain the same definition for Switch::ON and Switch::OFF. Since these are variables, and not functions, the linker would have to decide, arbitrarily, between them.

When you ran a test, what did the popular compilers say: gcc 3, gcc 4, microsoft C++ 2005, 2008, and 2010, and one of the Edison Design Groups' compilers such as http://www.comeaucomputing.com/ ?

Said test would consist of:

// Switch.h
class Switch {
public:
    static Switch const ON;
    static Switch const OFF;
    bool operator== (Switch const &s) const;
    bool operator!= (Switch const &s) const;
private:
    Switch () {}
    Switch (Switch const &); // no implementation
    Switch & operator= (Switch const &); // no implementation
};

Switch const Switch::ON;
Switch const Switch::OFF;

bool Switch::operator== (Switch const &s) const {
    return this == &s;
}

bool Switch::operator!= (Switch const &s) const {
    return this != &s;
}

and

// main.cpp
#include "Switch.h"

extern int another_test();

int main(int argc, char*argv[])
{
  another_test();
  const Switch& current_state = Switch::ON;
  const Switch& another_state = Switch::OFF;
  if (current_state == another_state) {
    return 1;
  } else if (current_state != another_state) {
    return 2;
  }
  return another_test();
}

and

// another_test.cpp
#include "Switch.h"

int another_test()
{
  const Switch& current_state = Switch::ON;
  const Switch& another_state = Switch::OFF;
  if (current_state == another_state) {
    return 4;
  } else if (current_state != another_state) {
    return 5;
  }
  return 6;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文