Инициализация статического константного массива
От: J-son  
Дата: 24.08.10 08:53
Оценка:
Здравствуйте, подскажите пожалуйста, как инициализировать статический константный массив, являющийся членом класса? Перепробовал несколько вариантов, не работает...

static char m_Ch[] = {'A', 'B', 'C'};//syntax error : '{'
static char* m_Ch = {'A', 'B', 'C'};//syntax error : '{'

static char m_Ch[3];//unresolved external symbol
Re: Инициализация статического константного массива
От: Bell Россия  
Дата: 24.08.10 08:58
Оценка: +3
Здравствуйте, 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


Ээээ...

//.h
struct st
{
   static int arr[3];
};

//.cpp
int st::arr[3] = {1, 2, 3};
Любите книгу — источник знаний (с) М.Горький
Re[2]: Инициализация статического константного массива
От: J-son  
Дата: 24.08.10 09:08
Оценка:
Здравствуйте, 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
что в принципе логично

убрал int, пишет опять syntax error : '{'
Re[3]: Инициализация статического константного массива
От: Bell Россия  
Дата: 24.08.10 09:14
Оценка: 3 (1)
Здравствуйте, J-son, Вы писали:


JS>Честно говоря, не понял, что вы написали...

JS>Сделал, как вы сказали, но выдалась ошибка
JS>int st::arr[3] = {1, 2, 3};//redefinition
JS>что в принципе логично

JS>убрал int, пишет опять syntax error : '{'


Я написал минимальный полный пример с инициализацией статического массива — члена, с указанием, какая часть кода находится в заголовке, а какая — в .срр — файле. Приведи свой минимальный полный пример, который иллюстрирует проблему, с разделением по файлам.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Инициализация статического константного массива
От: Кодт Россия  
Дата: 24.08.10 11:09
Оценка: 2 (1) +2
Здравствуйте, J-son, Вы писали:

B>>
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>убрал int, пишет опять syntax error : '{'


Не стоит изучать основы языка методом тыка
Перекуём баги на фичи!
Re[4]: Инициализация статического константного массива
От: Vain Россия google.ru
Дата: 24.08.10 11:30
Оценка: +1
Здравствуйте, Кодт, Вы писали:

JS>>Честно говоря, не понял, что вы написали...

К>Всё просто: в объявлении класса — только объявление статического члена. А затем в каком-нибудь одном месте — определение с инициализацией.
К>В одном — значит, в единственном .cpp файле. (Либо прибегнуть к компиляторной магии selectany).
Исключение — шаблоны, там можно (и нужно) в хедере определять.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: Инициализация статического константного массива
От: J-son  
Дата: 25.08.10 08:03
Оценка:
Здравствуйте, 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};

Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??

PS: Как мне нравится C#...
Re[5]: Инициализация статического константного массива
От: fgrdn Земля  
Дата: 25.08.10 08:12
Оценка:
Здравствуйте, J-son, Вы писали:

JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??

чо?
причем тут структура? в примере выше просто использована POD вместо класса.

JS>PS: Как мне нравится C#...

пиши на шарпе
in c/c++ we trust!
Re[5]: Инициализация статического константного массива
От: rg45 СССР  
Дата: 25.08.10 08:34
Оценка:
Здравствуйте, J-son, Вы писали:

JS>
int st::arr[3] = {1, 2, 3}// — это я писал в методе, а надо было написать вне метода

JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??

Ну почему же нельзя, можно:
class st
{
   static int arr[3];
};
int st::arr[3] = {1, 2, 3};

А вообще, вопросы желательно формулировать более внятно, а то приходится угадывать, что ты имеешь ввиду — то ли тебе не нравится, что определение статического массива приходится делать за пределами класса, то ли ты не разобрался в различиях между классами и структурами в C++, еще и какой-то метод тут каким-то боком фигурирует
--
Re[5]: Инициализация статического константного массива
От: Bell Россия  
Дата: 25.08.10 09:02
Оценка:
Здравствуйте, J-son, Вы писали:

JS>В общем, я разобрался, спасибо.

JS>int st::arr[3] = {1, 2, 3}// — это я писал в методе, а надо было написать вне метода, то есть примерно так

Да, именно так.

JS>int <имя класса>::st::arr[3] = {1, 2, 3};


JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??

Помести объявление массива в нужный тебе класс, и напиши потом в .срр — файле
int <имя класса>::arr[3] = {1, 2, 3};


JS>PS: Как мне нравится C#...

Любите книгу — источник знаний (с) М.Горький
Re[2]: Инициализация статического константного массива
От: J-son  
Дата: 25.08.10 11:24
Оценка:
Здравствуйте, 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>



А, все, извините, я просто запутался...
Я почему то решил, что данная структура равносильна моему массиву и поместил ее в класс вместо массива.
А оказывается, что данная структура равносильна классу, а массив массиву.
Не так понял просто...
Все, всем спасибо, еще раз извините!
Re: Инициализация статического константного массива
От: Андрюха  
Дата: 28.12.11 21:57
Оценка:
Чтоб не создавать еще один топик, задам вопрос тут.

Я наваял следующий класс


//.hpp
class SomeClass{
public:
    SomeClass(int i){}
}

class Foo{
    public:
static const N = 10;
        static SomeClass someArray[N]; 
};
//.cpp init someArray


Хотелось бы расширить его применимость, сделав его темплейтным классом:

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();


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

Благодарен за любой совет.
Re[2]: Инициализация статического константного массива
От: Сыроежка  
Дата: 28.12.11 22:29
Оценка:
Здравствуйте, Андрюха, Вы писали:

А>Чтоб не создавать еще один топик, задам вопрос тут.


А>Я наваял следующий класс



А>
А>//.hpp
А>class SomeClass{
А>public:
А>    SomeClass(int i){}
А>}

А>class Foo{
А>    public:
А>static const N = 10;
А>        static SomeClass someArray[N]; 
А>};
А>//.cpp init someArray
А>


А>Хотелось бы расширить его применимость, сделав его темплейтным классом:

А>

А>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 нельзя вызывать без указания объекта класса, так как эта функция является не статической.
Во-вторых, это не инициализация массива, а присваивание его элементам значений. Выдолжны же как-то определить свой массив, не так ли? А так как его размерность заранее неизвестна, то вам будет трудно его инициализировать, кроме как вызовом конструктора по умолчанию для его элементов. А у вашего типа элементов нет конструктора по умолчанию, а есть лишь конструктор с обязательным параметром.
Меня можно встретить на www.cpp.forum24.ru
Re[3]: Инициализация статического константного массива
От: Андрюха  
Дата: 28.12.11 23:29
Оценка:
Здравствуйте, Сыроежка, Вы писали:

С>Вы не можете таким образом инициализировать массив, так как статические члены класса не могут быть инициализированы при помощт вызова нестатических функций. То есть вашу функцию 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();
Re[3]: Инициализация статического константного массива
От: Pzz Россия https://github.com/alexpevzner
Дата: 29.12.11 00:46
Оценка:
Здравствуйте, J-son, Вы писали:

B>>
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] = ...; надо писать не в ашнике, а в сишнике — каком-то одном на всю программу.
Re[5]: Инициализация статического константного массива
От: Pzz Россия https://github.com/alexpevzner
Дата: 29.12.11 00:48
Оценка:
Здравствуйте, J-son, Вы писали:

JS>Все таки непонятно, почему надо использовать структуры? Почему без них нельзя объявить статический массив в классе??


Единственная разница между структурами и классами в c++, что в классе, если явно не указано, все по-дефолту private, а в структуре — public.
Re[6]: Инициализация статического константного массива
От: Андрюха  
Дата: 29.12.11 01:14
Оценка:
Здравствуйте, Pzz,

На вопросы J-son уже ответили, прокомментируйте пожалуйста мой вопрос чуть выше)
Re[4]: Инициализация статического константного массива
От: Андрюха  
Дата: 29.12.11 03:30
Оценка:
А>
А>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();
А>


Очень не хотелось менять интерфейс, поэтому выкрутился следующим образом:


class SomeClass{
public:
   SomeClass(int i){}
   SomeClass(){}
}

template <int N>
class Foo{
public:
        typedef SomeClass SomeClassArrayType[N];
        static SomeClassArrayType &someClassArray; 

private:
  

static  SomeClassArrayType & Initialize_someClassArray()
   {
     static SomeClassArrayType _someClassArray;
     bool bFirstTime = true;

     if(bFirstTime){
        for(int i = 0; i < N; ++i)
           _someClassArray[i] = SomeClass(i);
        bFirstTime = false;
     }

     return _someClassArray;
   }
};

template <int N>
Foo<N>::SomeClassArrayType & Foo<N>::someClassArray = Foo<N>::Initialize_someClassArray();
Re[5]: Инициализация статического константного массива
От: night beast СССР  
Дата: 29.12.11 05:19
Оценка: 1 (1)
Здравствуйте, Андрюха, Вы писали:


А>Очень не хотелось менять интерфейс, поэтому выкрутился следующим образом:


А>static  SomeClassArrayType & Initialize_someClassArray()
А>   {
А>     static SomeClassArrayType _someClassArray;
А>     bool bFirstTime = true;
А>   }
А>};


bFirstTime, если он действительно нужен, сделай статическим.
Re[4]: Инициализация статического константного массива
От: Masterkent  
Дата: 29.12.11 09:12
Оценка: 1 (1)
Андрюха:

А>А теперь будет работать? Или все зависит от порядка инициализации статических членов?


А>
А>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();
А>

Главная проблема тут в том, что если 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.

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.