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

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

class A {
private:
  static const int a = 4;
  /*...*/
};
61
задан jogojapan 30 October 2012 в 01:06
поделиться

4 ответа

ДА, вы можете, но только для типов 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, теперь (с компилятором, обеспечивающим эту функцию) вы можете инициализировать то, что вы хотите, прямо в объявлении члена класса.

70
ответ дан 24 November 2019 в 17:13
поделиться

Статические члены данных (только 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.

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

#include <iostream>
using namespace std;

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

const int X::a;

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

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

33
ответ дан 24 November 2019 в 17:13
поделиться

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

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

// .cpp
const foo A::bar = ...;
6
ответ дан 24 November 2019 в 17:13
поделиться

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

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

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

int main(){
   X<int> x;
}
13
ответ дан 24 November 2019 в 17:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: