Определение статических членов в C ++ - PullRequest
25 голосов
/ 21 августа 2010

Я пытаюсь определить общедоступную статическую переменную следующим образом:

public :
         static int j=0;        //or any other value too

Я получаю ошибку компиляции в этой самой строке: ISO C ++ запрещает инициализацию в классе неконстантного статического члена `j'.

  1. Почему это не разрешено в C ++?

  2. Почему константные члены допускаются для инициализации?

  3. Означает ли это, что статические переменные в C ++ не инициализируются 0, как в C?

Спасибо!

Ответы [ 5 ]

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

Вам нужно будет инициализировать статическую переменную в файле .cpp, а не в объявлении класса.

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

//Header file
class Test
{
  public:
    static int j;
};

//In cpp file

//Initialize static variables here.
int Test::j = 0;

//Constructor
Test::Test(void)
{
   //Class initialize code
}
18 голосов
/ 21 августа 2010

(1.) Почему это не разрешено в C ++?

Из Часто задаваемые вопросы по стилю и технике С ++ Бьярна Страуструпа : A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

(2.) Почему члены const могут инициализироваться?

[ прямо сказал это лучше ]

(3.) Означает ли это статические переменные в C ++ не инициализируются с 0 как в С?

Насколько я знаю, пока вы объявляете статический член var в .cpp, он будет инициализироваться нулем, если вы не укажете иначе:

// in some .cpp
int Test::j; // j = int();
18 голосов
/ 21 августа 2010

Почему это не разрешено в C ++?

До тех пор, пока вы не определите это, переменная не станет l-значением.

Почему константные члены допускаются для инициализации?

Даже в этом случае определение требуется, если вы собираетесь взять адрес переменной.

9.4.2 Элементы статических данных

2 Объявление члена статических данных в его определении класса не является определением иможет быть неполного типа, кроме cv-квалифицированного void.Определение для статического члена данных должно появиться в области пространства имен, включающей определение класса члена.В определении в области пространства имен имя члена статических данных должно быть квалифицировано по имени его класса с помощью оператора ::.Выражение инициализатора в определении статического члена данных находится в области его класса

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

class S {
      static const int size = 42;
      float array[ size ];
};

Означает ли это, что статические переменные в C ++ не инициализируются с 0, как в C?

Нет, они:

3.6.2 Инициализация не-локальные переменные

Переменные со статической продолжительностью хранения (3.7.1) или продолжительностью хранения потока (3.7.2) должны быть обнулены (8.5) перед любой другой инициализацией.

Хотя в C ++ 0x дела обстоят немного сложнее.Все литеральные типы теперь могут быть инициализированы (в отличие от только целочисленных типов в текущем стандарте), что означает, что все скалярные типы (включая числа с плавающей запятой) и некоторые типы классов теперь могут быть инициализированы с помощью инициализатора в объявлении.

8 голосов
/ 21 августа 2010

Краткий ответ:

Это эквивалентно высказыванию extern int Test_j = 0;.

Если он скомпилируется, что произойдет? Каждый исходный файл, включая заголовочный файл вашего класса, будет определять символ с именем Test :: j, инициализированный равным 0. Компоновщику это не нравится.

2 голосов
/ 17 мая 2016
class GetData        
{    
private:     
static int integer;   //Static variable must be defined with the extension of keyword static;      
public:      
static void enter(int x)      
{       
integer = x;  //static variable passed through the static function    
}
static int  show()   //declared and defined
{
    return integer;   //will return the integer's value
}        
};        
int GetData::integer = 0;    //Definition of the static variable       
int main()      
{      
   GetData::enter(234);    //value has been passed through the static function enter. Note that class containing static variables may not have the object in main. They can be called by scope resolution operator in main.
   cout<<GetData::show();      
}     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...