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

时间:2011-05-16 22:02:48

标签: c++ static initialization stateless

假设我有一个T类

  1. T没有虚拟功能。
  2. T实例没有状态。
  3. T拥有自己的静态成员实例。
  4. T本身没有其他状态。
  5. 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;
    }
    

3 个答案:

答案 0 :(得分:2)

我感兴趣的是你从命名空间或类中包含的枚举中看到的优点:

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;

答案 1 :(得分:2)

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

答案 2 :(得分:0)

你真的打算用指针值比较“状态”吗?我同意@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;
}