C ++ статическая инициализация класса без сохранения состояния - PullRequest
7 голосов
/ 17 мая 2011

Предположим, у меня есть класс T, в котором

  1. T не имеет виртуальных функций.
  2. T экземпляры не имеют состояния.
  3. T имеет статические экземпляры-члены себя.
  4. Сам T не имеет другого состояния.

Может ли статическая инициализация C ++ фиаско испортить мою программу?Я так не думаю, потому что даже если один из статических экземпляров не инициализируется перед использованием, это не должно иметь значения, потому что объекты T не имеют состояния.

Я заинтересован в том, чтобы сделать это для классов, подобных enum, например, так:


// 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 ]

2 голосов
/ 17 мая 2011

Меня интересует, какие преимущества вы видите, скажем, от перечисления, заключенного в пространство имен или в класс:

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;
2 голосов
/ 17 мая 2011

Чтобы ответить на первую часть вашего вопроса, если у T есть конструктор, который имеет побочные эффекты, то вы фактически можете сгореть от статического провала инициализации.

0 голосов
/ 17 мая 2011

Вы действительно намереваетесь использовать значения указателя для сравнения "состояния"?Я согласен с @Drew, это интересная идея.Я не уверен, что стандарт гарантированно работает, хотя, если предположить, что это реализация только для заголовка.

Рассмотрим, что происходит, когда несколько объектов компиляции содержат одно и то же определение для Switch::ON иSwitch::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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...