Как получить доступ к элементам структуры с помощью указателей? - PullRequest
1 голос
/ 15 сентября 2011

Проблема заключается в создании таблицы данных std::vector (struct MegaTable, из приведенного ниже примера), в которой элементы (struct DataItem, из примера ниже) могут иметь указатель на весь массив данных.

Вот мой код:

#include <vector>

struct MegaDataItem;

struct DataItem 
{
     int            a_;
     char*          ch_;

     MegaDataItem*  ptr_;

     DataItem( int _a, char* _ch, MegaDataItem* ptr )
          : a_( _a )
          , ch_( _ch )
          , ptr_( ptr )
     {}
};
typedef std::vector< DataItem > DataTable;


struct MegaDataItem 
{
     int            b_;
     DataTable      data_;

     MegaDataItem( int _b )
          : b_( _b )
     {
          for ( int j = 15; j >= 10; j-- )
          {
               DataItem item( j, "", this );
               data_.push_back( item );
          }
     }
};
typedef std::vector< MegaDataItem > MegaTable;


int main( int argc, char** argv )
{
     MegaTable table;

     for ( int i = 0; i < 5; i++ )
     {
          MegaDataItem megaItem( i );
          table.push_back( megaItem );
     }
     return 0;
}

И отладочный снимок из MSVS:

enter image description here

Как видите, указатель ptr_ везде равен 0x0031fccc , но это не правильно!Указатель должен состоять из правильных struct MegaDataItem данных, где все struct DataItem существуют ...

Спасибо за помощь!

PS.Я знаю, что это не сложный вопрос, но я не могу понять, как заставить все это работать!


ОБНОВЛЕНИЕ (исправленное решение): PS: спасибоjpalecek!:)

MegaDataItem( const MegaDataItem& other )
          : b_( other.b_ )
     {
          data_.clear();
          DataTable::const_iterator d_i( other.data_.begin() ), d_e( other.data_.end() );
          for ( ; d_i != d_e; ++d_i )
               data_.push_back( DataItem( (*d_i).a_, (*d_i).ch_, this ) );
     }

void operator=( const MegaDataItem& other )
     {
          b_ = other.b_;

          data_.clear();
          DataTable::const_iterator d_i( other.data_.begin() ), d_e( other.data_.end() );
          for ( ; d_i != d_e; ++d_i )
               data_.push_back( DataItem( (*d_i).a_, (*d_i).ch_, this ) );
     }

Ответы [ 2 ]

3 голосов
/ 15 сентября 2011

Проблема в том, что ваша структура MegaDataItem не может быть скопирована и назначена (если вы копируете или присваиваете vector в MegaDataItem, обратные указатели будут указывать на исходный MegaDataItem, что неверно).Вы должны изменить это.

В частности, вам нужно будет реализовать конструктор копирования и оператор присваивания.В них вы должны перенаправить указатели ptr_ в DataItem s на новый MegaDataItem.

Пример реализации:

MegaDataItem(const MegaDataItem& other) : b_(other.b_) {
  // fill data
  for(DataItem& item : other.data_)
    data_.push_back(DataItem(item.a_, item.ch_, this));
}

operator=(const MegaDataItem& other) {
  b_=other.b_;
  data_.clear();
  for(DataItem& item : other.data_)
    data_.push_back(DataItem(item.a_, item.ch_, this));
}

Кстати, в зависимости от того, что ch_в DataItem означает, что вы можете реализовать их и в DataItem.

0 голосов
/ 15 сентября 2011

Эх, похоже, работает как задумано. Вы передаете this конструктору DataItem, поэтому, конечно, все DataItem, созданные MegaDataItem, будут иметь одинаковое значение ptr_.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...