Как инициализировать статический член const в C ++? - PullRequest
60 голосов
/ 20 августа 2010

Можно ли инициализировать статическое значение const вне конструктора?Можно ли его инициализировать в том же месте, где находятся объявления членов?

class A {
private:
  static const int a = 4;
  /*...*/
};

Ответы [ 4 ]

68 голосов
/ 20 августа 2010

ДА вы можете, но только для типов int.Если вы хотите, чтобы ваш статический член был любого другого типа, вам нужно определить его где-нибудь в файле cpp.

class A{
private:
 static const int a = 4; // valid
 static const std::string t ; // can't be initialized here
 ...
 ...
};


// in a cpp file where the static variable will exist 
const std::string A::t = "this way it works";

Также обратите внимание, что это правило было удалено в C ++ 11, теперь(с помощью компилятора, предоставляющего эту функцию) вы можете инициализировать то, что вы хотите, непосредственно в объявлении члена класса.

32 голосов
/ 20 августа 2010

Элементы статических данных (только C ++)

Объявление статического члена данных в списке членов класса не является определением. Вы должны определить статический член вне объявления класса в области имен. Например:

class X
{
public:
      static int i;
};
int X::i = 0; // definition outside class declaration

После определения статического члена данных он существует, даже если не существует объектов класса статического члена данных. В приведенном выше примере объекты класса X не существуют, хотя статический член данных X :: i был определен.

Статические члены-данные класса в области пространства имен имеют внешнюю связь. Инициализатор для статического члена данных находится в области действия класса, объявляющего член.

Статический элемент данных может быть любого типа, кроме void или void, квалифицируемых как const или volatile. Вы не можете объявить статический член данных как изменяемый.

Вы можете иметь только одно определение статического члена в программе. Неназванные классы, классы, содержащиеся в безымянных классах, и локальные классы не могут иметь статических членов данных.

Статические члены-данные и их инициализаторы могут получать доступ к другим статическим закрытым и защищенным членам своего класса. В следующем примере показано, как можно инициализировать статические члены, используя другие статические члены, даже если эти члены являются закрытыми:

class C {
      static int i;
      static int j;
      static int k;
      static int l;
      static int m;
      static int n;
      static int p;
      static int q;
      static int r;
      static int s;
      static int f() { return 0; }
      int a;
public:
      C() { a = 0; }
      };

C c;
int C::i = C::f();    // initialize with static member function
int C::j = C::i;      // initialize with another static data member
int C::k = c.f();     // initialize with member function from an object
int C::l = c.j;       // initialize with data member from an object
int C::s = c.a;       // initialize with nonstatic data member
int C::r = 1;         // initialize with a constant value

class Y : private C {} y;

int C::m = Y::f();
int C::n = Y::r;
int C::p = y.r;       // error
int C::q = y.f();     // error

Инициализация C :: p и C :: q вызывает ошибки, поскольку y является объектом класса, который является производным от C, и его члены недоступны для членов C.

Если член статических данных имеет константный интеграл или константный тип перечисления, вы можете указать постоянный инициализатор в объявлении члена статических данных. Этот инициализатор констант должен быть выражением интегральной константы. Обратите внимание, что инициализатор констант не является определением. Вам все еще нужно определить статический член во вложенном пространстве имен. Следующий пример демонстрирует это:

#include <iostream>
using namespace std;

struct X {
  static const int a = 76;
};

const int X::a;

int main() {
  cout << X::a << endl;
}

Жетоны = 76 в конце объявления статического члена данных a являются инициализатором констант.

13 голосов
/ 20 августа 2010

Для полноты картины добавляю статические переменные-члены шаблона.

template<class T> struct X{
   static T x;
};

template<class T> T X<T>::x = T();

int main(){
   X<int> x;
}
6 голосов
/ 20 августа 2010

Вы не можете инициализировать статические члены внутри конструкторов. Интегральные типы вы можете инициализировать встроенными при их объявлении. Другие статические члены должны быть определены (в .cpp) файле:

// .h
class A{
private:
 static const int a = 4;
 static const foo bar;
 ...
 ...
};

// .cpp
const foo A::bar = ...;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...