определение целочисленного статического const в классе, чей файл .h включен в несколько файлов cpp - PullRequest
0 голосов
/ 09 апреля 2011
A.h

class A  
{  
   private:
     static const int b = 50;
     int c[b];
 };

 A.cpp

 #include "A.h"
 const int A::b;

 C.cpp

 #include "A.h"

Компилятор выдает мне предупреждение о том, что b определяется несколько раз, а один игнорируется. Мне нужно определить его в классе, так как мне нужно инициализировать массив. В качестве альтернативы мне нужно использовать подход enum, чтобы сделать это. Но я хотел знать, возможно ли это?

Ответы [ 2 ]

6 голосов
/ 09 апреля 2011

Я собираюсь предположить, что вы используете Visual C ++, который имеет довольно ужасное расширение языка, как описано в «Расширения Microsoft для C и C ++» :

Вне класса Определение статических константных (или перечислимых) членов

В соответствии со стандартом (/Za) вам необходимо создать внеклассное определение для элементов данных. Например,

class CMyClass {
    static const int max = 5;
    int m_array[max];
}
...
const int CMyClass::max;   // out of class definition

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

Чтобы избежать ошибок, когда предоставляется определение вне класса (когда определение вне класса предоставляется в файле заголовка, а файл заголовка включен в несколько исходных файлов), вы должны использовать selectany. Например:

__declspec(selectany) const int CMyClass::max = 5;

Флаг /Ze включен по умолчанию. Вы должны явно использовать флаг /Za, если не хотите расширений языка.

Код в том виде, в котором он написан, без ошибок компилируется и связывается с использованием g ++ 4.5.2, Clang 3.0 и Visual C ++ 2010 с установленным флагом /Za.

Удаление определения из файла .cpp решает проблему, если вы хотите скомпилировать с Visual C ++, но тогда оно не будет работать с другими компиляторами (или с /Za), если вы попытаетесь использовать элемент данных. Для переносимого обходного пути вы можете использовать блок условной компиляции, который проверяет, включены ли расширения:

#ifndef _MSC_EXTENSIONS
const int A::b;
#endif
0 голосов
/ 09 апреля 2011

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

Возьмите его из .cpp, и все будет хорошо.Только не пытайтесь взять его адрес.

...