2010-08-20 5 views
45

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

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

Да, у вас есть работы (но только для интегральных типов). – UncleBens

+3

Просто хотел добавить, что 'static' не имеет ничего общего с конструкторами, поскольку члены' static' не специфичны для данного экземпляра и существуют вне его. – ereOn

+0

На самом деле вы * должны * инициализировать const statics вне конструктора класса. В противном случае это не будет постоянным. DUCY? –

ответ

54

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

+0

почему static const double = value; не работает? – anarhikos

+2

@anarhikos - инициализация в классе работает только для интегральных типов. 'double' не является интегральным типом. –

+1

@anrhikos: Вот почему вы не должны определять внутри класса. Вы должны определить вне класса в соответствии с практикой (см. Мой ответ) – 2010-08-20 13:35:11

27

Static data members (C++ only)

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

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

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

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

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

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

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

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 :: р и C :: Q ошибки причина, потому что у является объектом класс, который получен частным образом от 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 в конце объявления статического члена данных, а константа инициализатор.

0

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

3

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

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

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

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

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

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

int main(){ 
    X<int> x; 
} 
Смежные вопросы