B>>//.h
B>>struct st
B>>{
B>> static int arr[3];
B>>};
B>>//.cpp
B>>int st::arr[3] = {1, 2, 3};
B>>
JS>Честно говоря, не понял, что вы написали...
Всё просто: в объявлении класса — только объявление статического члена. А затем в каком-нибудь одном месте — определение с инициализацией.
В одном — значит, в единственном .cpp файле. (Либо прибегнуть к компиляторной магии selectany).
JS>Сделал, как вы сказали, но выдалась ошибка JS>int st::arr[3] = {1, 2, 3};//redefinition JS>что в принципе логично
Это значит, что
— либо определение встретилось дважды (многократный копипаст, кривое включение файлов)
— либо оно действительно не соответствует объявлению (кривой копипаст; в исходном коде Bell-а всё правильно)
— либо какая-то глупая очепятка всё поломала, — например, отсутствует ';' после объявления структуры
JS>Честно говоря, не понял, что вы написали... JS>Сделал, как вы сказали, но выдалась ошибка JS>int st::arr[3] = {1, 2, 3};//redefinition JS>что в принципе логично
JS>убрал int, пишет опять syntax error : '{'
Я написал минимальный полный пример с инициализацией статического массива — члена, с указанием, какая часть кода находится в заголовке, а какая — в .срр — файле. Приведи свой минимальный полный пример, который иллюстрирует проблему, с разделением по файлам.
Главная проблема тут в том, что если m_dummy не используется ни в одном потенциально вычислимом выражении, то определение этого member-а просто не будет инстанцировано, и, соответственно, его инициализация не будет производиться:
14.7.1/2:
Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.
Здравствуйте, Кодт, Вы писали:
JS>>Честно говоря, не понял, что вы написали... К>Всё просто: в объявлении класса — только объявление статического члена. А затем в каком-нибудь одном месте — определение с инициализацией. К>В одном — значит, в единственном .cpp файле. (Либо прибегнуть к компиляторной магии selectany).
Исключение — шаблоны, там можно (и нужно) в хедере определять.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, подскажите пожалуйста, как инициализировать статический константный массив, являющийся членом класса? Перепробовал несколько вариантов, не работает...
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, J-son, Вы писали:
JS>>Здравствуйте, подскажите пожалуйста, как инициализировать статический константный массив, являющийся членом класса? Перепробовал несколько вариантов, не работает...
JS>>static char m_Ch[] = {'A', 'B', 'C'};//syntax error : '{' JS>>static char* m_Ch = {'A', 'B', 'C'};//syntax error : '{'
JS>>static char m_Ch[3];//unresolved external symbol
B>Ээээ...
B>
B>//.h
B>struct st
B>{
B> static int arr[3];
B>};
B>//.cpp
B>int st::arr[3] = {1, 2, 3};
B>
Честно говоря, не понял, что вы написали...
Сделал, как вы сказали, но выдалась ошибка
int st::arr[3] = {1, 2, 3};//redefinition
что в принципе логично
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, J-son, Вы писали:
JS>>Честно говоря, не понял, что вы написали... JS>>Сделал, как вы сказали, но выдалась ошибка JS>>int st::arr[3] = {1, 2, 3};//redefinition JS>>что в принципе логично
JS>>убрал int, пишет опять syntax error : '{'
B>Я написал минимальный полный пример с инициализацией статического массива — члена, с указанием, какая часть кода находится в заголовке, а какая — в .срр — файле. Приведи свой минимальный полный пример, который иллюстрирует проблему, с разделением по файлам.
В общем, я разобрался, спасибо.
int st::arr[3] = {1, 2, 3}// — это я писал в методе, а надо было написать вне метода, то есть примерно так
int <имя класса>::st::arr[3] = {1, 2, 3};
Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??
Здравствуйте, J-son, Вы писали:
JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??
чо?
причем тут структура? в примере выше просто использована POD вместо класса.
JS>PS: Как мне нравится C#...
пиши на шарпе
int st::arr[3] = {1, 2, 3}// — это я писал в методе, а надо было написать вне метода
JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??
Ну почему же нельзя, можно:
class st
{
static int arr[3];
};
int st::arr[3] = {1, 2, 3};
А вообще, вопросы желательно формулировать более внятно, а то приходится угадывать, что ты имеешь ввиду — то ли тебе не нравится, что определение статического массива приходится делать за пределами класса, то ли ты не разобрался в различиях между классами и структурами в C++, еще и какой-то метод тут каким-то боком фигурирует
Здравствуйте, J-son, Вы писали:
JS>В общем, я разобрался, спасибо. JS>int st::arr[3] = {1, 2, 3}// — это я писал в методе, а надо было написать вне метода, то есть примерно так
Да, именно так.
JS>int <имя класса>::st::arr[3] = {1, 2, 3};
JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??
Помести объявление массива в нужный тебе класс, и напиши потом в .срр — файле
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, J-son, Вы писали:
JS>>Здравствуйте, подскажите пожалуйста, как инициализировать статический константный массив, являющийся членом класса? Перепробовал несколько вариантов, не работает...
JS>>static char m_Ch[] = {'A', 'B', 'C'};//syntax error : '{' JS>>static char* m_Ch = {'A', 'B', 'C'};//syntax error : '{'
JS>>static char m_Ch[3];//unresolved external symbol
B>Ээээ...
B>
B>//.h
B>struct st
B>{
B> static int arr[3];
B>};
B>//.cpp
B>int st::arr[3] = {1, 2, 3};
B>
А, все, извините, я просто запутался...
Я почему то решил, что данная структура равносильна моему массиву и поместил ее в класс вместо массива.
А оказывается, что данная структура равносильна классу, а массив массиву.
Не так понял просто...
Все, всем спасибо, еще раз извините!
Хотелось бы расширить его применимость, сделав его темплейтным классом:
class SomeClass{
public:
SomeClass(int i){}
}
template <int N>
class Foo{
public:
static SomeClass someArray[N];
};
Вопрос в том, как инициализировать статический массив в этом случае?
Я не хочу заставлять пользователя вызывать статическую функцию, инициализирующую этот массив.
Т.е. я хочу, чтоб все само инициализировалось автоматически.
Я подумал о таком способе:
class SomeClass{
public:
SomeClass(int i){}
}
template <int N>
class Foo{
public:
static SomeClass someArray[N];
private:
static int m_dummy;
int Initialize_someArray()
{
for(int i = 0; i < N; ++i)
someArray[i] = SomeClass(i);
}
};
template <int N>
int Foo<N>::m_dummy = Initialize_someArray();
но не уверен, что он будет работать всегда из-за возможной неопределенности с порядком инициализации/выделения памяти.
А>Вопрос в том, как инициализировать статический массив в этом случае? А>Я не хочу заставлять пользователя вызывать статическую функцию, инициализирующую этот массив. А>Т.е. я хочу, чтоб все само инициализировалось автоматически.
А>Я подумал о таком способе: А>
А>но не уверен, что он будет работать всегда из-за возможной неопределенности с порядком инициализации/выделения памяти.
А>Благодарен за любой совет.
Вы не можете таким образом инициализировать массив, так как статические члены класса не могут быть инициализированы при помощт вызова нестатических функций. То есть вашу функцию Initialize_someArray нельзя вызывать без указания объекта класса, так как эта функция является не статической.
Во-вторых, это не инициализация массива, а присваивание его элементам значений. Выдолжны же как-то определить свой массив, не так ли? А так как его размерность заранее неизвестна, то вам будет трудно его инициализировать, кроме как вызовом конструктора по умолчанию для его элементов. А у вашего типа элементов нет конструктора по умолчанию, а есть лишь конструктор с обязательным параметром.
Здравствуйте, Сыроежка, Вы писали:
С>Вы не можете таким образом инициализировать массив, так как статические члены класса не могут быть инициализированы при помощт вызова нестатических функций. То есть вашу функцию Initialize_someArray нельзя вызывать без указания объекта класса, так как эта функция является не статической. С>Во-вторых, это не инициализация массива, а присваивание его элементам значений. Выдолжны же как-то определить свой массив, не так ли? А так как его размерность заранее неизвестна, то вам будет трудно его инициализировать, кроме как вызовом конструктора по умолчанию для его элементов. А у вашего типа элементов нет конструктора по умолчанию, а есть лишь конструктор с обязательным параметром.
Спасибо, исправил.
А теперь будет работать? Или все зависит от порядка инициализации статических членов?
class SomeClass{
public:
SomeClass(int i){}
SomeClass(){}
}
template <int N>
class Foo{
public:
static SomeClass someArray[N];
private:
static int m_dummy;
static int Initialize_someArray()
{
for(int i = 0; i < N; ++i)
someArray[i] = SomeClass(i);
}
};
template <int N>
int Foo<N>::m_dummy = Foo<N>::Initialize_someArray();
B>>//.h
B>>struct st
B>>{
B>> static int arr[3];
B>>};
B>>//.cpp
B>>int st::arr[3] = {1, 2, 3};
B>>
JS>Честно говоря, не понял, что вы написали... JS>Сделал, как вы сказали, но выдалась ошибка JS>int st::arr[3] = {1, 2, 3};//redefinition JS>что в принципе логично
int str::arr[3] = ...; надо писать не в ашнике, а в сишнике — каком-то одном на всю программу.
Здравствуйте, J-son, Вы писали:
JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??
Единственная разница между структурами и классами в c++, что в классе, если явно не указано, все по-дефолту private, а в структуре — public.