Определение целочисленного статического 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, и все будет хорошо. Только не пытайтесь взять адрес этого.