Определение целочисленного статического const в классе, чей файл.h включен в несколько файлов cpp

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 ответа

Я собираюсь догадаться, что вы используете 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

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

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

Другие вопросы по тегам