Подтвердить что ты не робот

Как инициализировать статический член const в С++?

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

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

Ответ 1

ДА вы можете, но только для типов 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";

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

Ответ 2

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

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

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

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

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

Элемент статических данных может быть любого типа, за исключением 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.

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

#include <iostream>
using namespace std;

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

const int X::a;

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

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

Ответ 3

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

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

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

int main(){
   X<int> x;
}

Ответ 4

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

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

// .cpp
const foo A::bar = ...;

Ответ 5

Если я правильно помню, вы не можете определить его внутри класса. Вы явно должны определить его снаружи, как указано pablo.