Почему инициализация целочисленной переменной-члена (которая не является константной) не разрешена в C ++? - PullRequest
9 голосов
/ 01 декабря 2010

Мой компилятор C ++ жалуется, когда я пытаюсь инициализировать переменную-член int в определении класса. Он говорит, что «внутри класса могут быть инициализированы только статические интегральные члены-данные». Можете ли вы объяснить обоснование этого ограничения (если возможно, с примером).

Ответы [ 5 ]

11 голосов
/ 01 декабря 2010

Потому что это не разрешено в текущем стандарте. Согласно Бьярне , вы сможете сделать это в C ++ 0x. Если вам это действительно нужно, попробуйте установить компилятор на C ++ 0x (-std=c++0x в GCC) и посмотрите, поддерживает ли ваш компилятор.

8 голосов
/ 01 декабря 2010

Обоснованием является "низкоуровневая" природа C ++.Если это позволит, компилятору потребуется сгенерировать код инициализации для всех конструкторов, который не совсем понятен разработчику.

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

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

4 голосов
/ 01 декабря 2010

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

struct Example {
  int n;
  Example() : n(42) {}
};

Ограничение const существует, потому что случай const обрабатывается специально (а не наоборот), так чтоСтатические интегральные члены const обычно могут обрабатываться так, как если бы они имели внутреннюю связь, подобно переменным const в области имен (C ++ 03 §7.1.5.1p2, если вам интересно).В первую очередь полезно использовать члены в целочисленных константных выражениях, таких как размеры массивов.

3 голосов
/ 01 декабря 2010

Я просто предполагаю, что вы пытаетесь сделать это:

class foo {
    int m_iX = 5;
};

Это потребует запуска кода в конструкторе, поскольку каждый вновь созданный экземпляр должен будет инициализировать эту переменную.В C ++ весь код, который выполняется во время конструктора (к счастью), содержится в самом конструкторе, поэтому сразу становится очевидным, что влечет за собой конструкция класса.Кроме того, поскольку класс может иметь любое количество конструкторов (включая конструкторы копирования), было бы неоднозначно, когда эта инициализация должна или не должна иметь место.

Вы можете сделать это:

class foo {
    enum {
       CONSTANT = 8
    };
};

Это позволяет использовать foo::CONSTANT.Это работает, так как это будет для каждого класса, а не для каждого экземпляра.

Аналогично, вы можете сделать это:

class foo {
    static int sm_iX;
};

в .cpp:

int foo::sm_ix = 5;

Опять же, это для каждого класса, а не для каждого экземпляра, и как таковое не имеет отношения к созданию фактического экземпляра.

Бонус - если вы объявите этот int const, многие компиляторы могут оценить его при компиляции.время.

0 голосов
/ 01 декабря 2010

Арун,

Я полагаю, ваш вопрос связан с
Ошибка компилятора C2864

Чтобы достичь того, что вы хотите сделать, C ++ требует от вас инициализации экземпляраконкретные элементы (т. е. нестатические, не затратные) либо в теле конструктора, либо в списке инициализации.

...