2015-07-14 4 views
-1

Похоже, я пропустил что-то принципиальное здесь, но не получилось.Инициализировать закрытый массив с неизвестным количеством элементов (C++ 98)

Ниже приведен фрагмент и соответствующий ему выход.

Что я хотел сделать: - Объявить и инициализировать массив структур, не зная количества элементов заранее. - Идеально сам массив и его количество элементов: пользователей.

Что я пробовал:

  • Заявленный m_member_tab[] и m_num_members как частные.
  • Создана функция Init(), которая инициализирует объект m_member_tab[] и вычисляет m_num_members.

Результат:

  • m_member_tab[] инициализируется нормально (смотри ниже выход).
  • НО внутри конструктора (после звонка Init), m_member_tab поврежден.

    #include <iostream> 
    using std::cout; using std::endl; 
    
    class TArrayTest 
    { 
        public: 
         TArrayTest(); 
    
        private: 
         void Init(); 
    
         typedef struct _TMember 
         { 
          int m_key; 
          int m_val; 
         } 
         TMember; 
    
         TMember m_member_tab[]; 
         int m_num_members; 
    }; 
    
    TArrayTest::TArrayTest() 
    { 
        Init(); 
        cout << "Ctor: Number of elements = " << m_num_members << endl; 
        for(int i = 0; i < m_num_members; i++) 
        { 
         cout << "Ctor: " 
          << "key " << m_member_tab[i].m_key 
          << " - val " << m_member_tab[i].m_val 
          << endl; 
        } 
    }; 
    
    void TArrayTest::Init() 
    { 
        TMember m_member_tab[] = 
        { 
         { 1, 100 }, 
         { 2, 200 }, 
         { 3, 300 }, 
         { 4, 400 }, 
         { 5, 500 }, 
        }; 
        m_num_members = sizeof(m_member_tab)/sizeof(TMember); 
        cout << "Init: Number of elements = " << m_num_members << endl; 
        for(int i = 0; i < m_num_members; i++) 
        { 
         cout << "Init: " 
          << "key " << m_member_tab[i].m_key 
          << " - val " << m_member_tab[i].m_val 
          << endl; 
        } 
    } 
    
    int main() 
    { 
        TArrayTest test; 
    } 
    

Выход:

Init: Number of elements = 5 
    Init: key 1 - val 100 
    Init: key 2 - val 200 
    Init: key 3 - val 300 
    Init: key 4 - val 400 
    Init: key 5 - val 500 
    Ctor: Number of elements = 5 
    Ctor: key 5 - val 32766 
    Ctor: key 0 - val 0 
    Ctor: key 0 - val 0 
    Ctor: key -1212526907 - val 32623 
    Ctor: key 0 - val 0 

ответ

3

Это заявление члена:

TMember m_member_tab[]; 

не действует C++.

Существует дополнительная проблема в функции init, где вы объявляете локальную переменную с тем же именем, но это не имеет значения: указанное выше объявление не просто недействительно, но так как оно не находится в конце структуры это даже не имеет смысла как расширение языка.

Вместо этого используйте std::vector, как это:

std::vector<TMember> m_member_tab; 

Он отслеживает размер массива, так что вам не нужно, что дополнительный член.


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

Вы можете найти информацию о конструкторах в любом учебнике и любом вводном учебнике на C++.

Механизм с поддержкой языка имеет множество преимуществ по сравнению с функцией init.


О, и видя, как каждый элемент массива будет содержать ключ и значение, не рассмотрит std::map, или, если вы можете использовать C++ 11, а не только C++ 98/C03, std::unordered_map (более быстрый, но не отсортированный обход ключей).

1

в первой строке ничтожной TArrayTest :: Init():

TMember m_member_tab[] = 
{ 
    { 1, 100 }, 
    { 2, 200 }, 
    { 3, 300 }, 
    { 4, 400 }, 
    { 5, 500 }, 
}; 

вы объявляете "m_member_tab" временная переменная, а не член переменная. Вы должны написать так: m_member_tab [] = { {1, 100}, {2, 200}, {3, 300}, {4, 400}, {5, 500}, } ;

+0

Вы пробовали это. –

+0

Это само по себе не помогает. Но в любом случае +1 для указания моей ошибки использования безрассудного использования temp var. – artm

1

Функция, которую вы пытаетесь использовать, не существует на языке C++. Недопустимо использование [] в объявлениях статического массива нестатического типа. Он разрешен в объявлениях статических элементов-членов, но не в нестатических.

Даже если ваш компилятор каким-то образом разрешает это объявление, он, вероятно, интерпретирует его как массив нулевого размера. Размер массива фиксирован в этой точке - невозможно каким-либо образом «перевести» его в более крупный массив позже.

Объявление элемента массива с [] может быть разрешено некоторыми компиляторами в качестве способа поддержки C-стиля "struct hack". Но это совершенно другой метод.

+0

Спасибо. Похоже, единственный способ (если мне нужно придерживаться C++ 98) - объявить массив _public_ struct. Затем в файле реализации (вне самого класса) я могу инициализировать массив, не зная количества элементов (после синтаксиса C99). Это работает, но мне не очень нравится тот факт, что сам массив (и тип структуры) должен быть _public_. Для использования _vector_ есть предложение выше. Но я не нашел способ инициализировать вектор structs так, как я сделал с массивом C99 (т. Е. Не зная количества элементов). – artm

+0

@artm: Хм ... Я не понимаю, как сделать публичный массив доступным здесь. Как я сказал выше, до тех пор, пока ваш массив остается нестационарным членом класса, невозможно «переопределить» количество элементов. – AnT

Смежные вопросы