На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> CArray<CArray<CString,LPCTSTR>> массив массивов как? , ошибочка
    Здраствуйте друзья, у меня тут очередной затык :)
    вот хочу поюзать сабжу:

    ExpandedWrap disabled
      typedef CArray<CString, LPCTSTR> CArrayStr;
       
          CArray<CArrayStr> arrayArrays;
          CArrayStr values;
          CString s;
       
          for (int i = 0; i < 10; ++i)
          {
              for (int k = 0; k < 100; ++k)
              {      
                  s.Format(_T("%d"), i);
                  values.Add(s);
              }
       
              arrayArrays.Add(values);
          }

    а он пишет: "error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'"
    понятно что operator = нет доступа, но что делать то?! :wacko:
      Цитата Cfon @
      понятно что operator = нет доступа, но что делать то?! :wacko:

      Не писать так.

      Добавлено
      Используй std::vector<CArrayStr>

      Добавлено
      Цитата KILLER @
      Используй std::vector<CArrayStr>

      Вернее наоборот, я напутал, в тайпдефе вектор используй. CArray нельзя копировать, вектор можно:
      ExpandedWrap disabled
            typedef std::vector<CString> CArrayStr;
         
            CArray<CArrayStr, CArrayStr> arrayArrays;
            CArrayStr values;
            CString s;
         
            for (int i = 0; i < 10; ++i)
            {
                for (int k = 0; k < 100; ++k)
                {
                    s.Format(_T("%d"), i);
                    values.push_back(s);
                }
         
                arrayArrays.Add(values);
            }


      Добавлено
      Либо как вариант можешь написать свой класс, и отнаследоваться от CArray и там реализовать копирование.
      Сообщение отредактировано: KILLER -
        Цитата KILLER @
        Цитата Cfon @
        понятно что operator = нет доступа, но что делать то?! :wacko:

        Не писать так.

        Скрытый текст
        Добавлено
        Используй std::vector<CArrayStr>

        Добавлено
        Цитата KILLER @
        Используй std::vector<CArrayStr>

        Вернее наоборот, я напутал, в тайпдефе вектор используй. CArray нельзя копировать, вектор можно:
        ExpandedWrap disabled
              typedef std::vector<CString> CArrayStr;
           
              CArray<CArrayStr, CArrayStr> arrayArrays;
              CArrayStr values;
              CString s;
           
              for (int i = 0; i < 10; ++i)
              {
                  for (int k = 0; k < 100; ++k)
                  {
                      s.Format(_T("%d"), i);
                      values.push_back(s);
                  }
           
                  arrayArrays.Add(values);
              }


        Добавлено
        Либо как вариант можешь написать свой класс, и отнаследоваться от CArray и там реализовать копирование.

        я так и делал в своем демо (которое супер-пупер :D) создавал класс, но теперь потребовался массив массивов CArray, а тут такие пироги :unsure:
        лана пока сделаю через вектор, но не люблю мешать разные библиотеки.

        Добавлено
        не я один работаю на MFC :D
        http://stackoverflow.com/questions/4168964...-results-in-mfc
        Сообщение отредактировано: Cfon -
          Цитата Cfon @
          я так и делал в своем демо (которое супер-пупер :D) создавал класс, но теперь потребовался массив массивов CArray, а тут такие пироги :unsure:
          лана пока сделаю через вектор, но не люблю мешать разные библиотеки.

          Добавлено 5 минут назад
          не я один работаю на MFC :D
          http://stackoverflow.com/questions/4168964...-results-in-mfc

          Я бы так не заморачивался на самом деле. Очень часто, многие неверно понимают задачу, вернее не так, очень часто, многие выбирают неверное решение или не совсем верное решение для своей задачи, возможно из за отсутствия опыта.
          Порой по другому - сделать проще. Но не зная условия задачи - сложно будет подсказать более правильное решение. Вообще я например редко когда использую массив массивов, так как это усложняет работу с объектом. Может быть в твоем случае можно сделать более проще?
          Плюс ко всему, когда ты пишешь на MFC логику, не интерфейс, то учитывай то, что ты привязываешься к MFC. И если вдруг через пол года тебе вздумается переписать это все под какую нибудь другую ГУИ, например QT, то это будет очень трудозатратным. Поэтому логику работы лучше вообще не привязывать к конкретным API, а писать ее используя стандартные контейнеры, благо функционала там хватает с головой. И отделять это все от MFC. Тогда, в случае чего у тебя получится более универсальный продукт, который в конечном итоге ты сможешь прикрутить к разным ГУЯМ, а то и сделать поддержку нескольких.
          Сообщение отредактировано: KILLER -
            Цитата KILLER @
            Я бы так не заморачивался на самом деле. Очень часто, многие неверно понимают задачу, вернее не так, очень часто, многие выбирают неверное решение или не совсем верное решение для своей задачи, возможно из за отсутствия опыта.
            Порой по другому - сделать проще. Но не зная условия задачи - сложно будет подсказать более правильное решение. Вообще я например редко когда использую массив массивов, так как это усложняет работу с объектом. Может быть в твоем случае можно сделать более проще?
            Плюс ко всему, когда ты пишешь на MFC логику, не интерфейс, то учитывай то, что ты привязываешься к MFC. И если вдруг через пол года тебе вздумается переписать это все под какую нибудь другую ГУИ, например QT, то это будет очень трудозатратным. Поэтому логику работы лучше вообще не привязывать к конкретным API, а писать ее используя стандартные контейнеры, благо функционала там хватает с головой. И отделять это все от MFC. Тогда, в случае чего у тебя получится более универсальный продукт, который в конечном итоге ты сможешь прикрутить к разным ГУЯМ, а то и сделать поддержку нескольких.

            я пока так не умею мыслить в перспективе :huh:
            пишу гавнокод, потом рефакторинг, потом опять гавнокод и тд :D
            но за совет спс будем стараться :)

            Добавлено
            как уже сказал не лежит мешать std::vector c MFC СArray + CString хз почему чисто мое субъективное.. для практики решил поюзать массив указателей на массив через std::shared_ptr:
            ExpandedWrap disabled
                  typedef CArray<CString, LPCTSTR> ArrayStr;
                  
                  CArray<std::shared_ptr<ArrayStr>> grid;
                  CString s;
               
                  for (int i = 0; i < 10; ++i)
                  {
                      std::shared_ptr<ArrayStr> values(new ArrayStr);    
               
                      for (int k = 0; k < 100; ++k)
                      {      
                          s.Format(_T("%d"), i);
                          values->Add(s);
                      }
               
                      grid.Add(values);
                  }


            Добавлено
            Цитата KILLER @
            Вообще я например редко когда использую массив массивов, так как это усложняет работу с объектом. Может быть в твоем случае можно сделать более проще?

            в данном конкретном случае я хотел данные из запроса загрузить во временный массив и отсеить и/или отформатировать, а потом записать их в контролы диалога :)

            Добавлено
            вот Функция из моего демо:

            ExpandedWrap disabled
              void CCustomDlg::FillListCtrl(CListCtrl* list, LPCTSTR query, int id)
              {
                  CString qry;
                  qry.Format(query, id);
               
                  std::unique_ptr<CSqlStatement> stmt(theApp.mSQLiteDB.Statement(qry));
                  ASSERT(stmt);
               
                  /* вставка заголовка таблицы */
                  CString fieldName;
                  fieldName = _T("#");
                  list->InsertColumn(0, fieldName);
                  list->SetColumnWidth(0, 50);
               
                  for (int k = 1; k < stmt->Fields(); ++k)
                  {
                      fieldName = stmt->FieldName(k);
                      list->InsertColumn(k, fieldName);
                      list->SetColumnWidth(k, 100);
                  }
               
                  /* вставка данных в таблицу */
                  typedef CArray<CString, LPCTSTR> CArrayStr;
                  CArray<std::shared_ptr<CArrayStr>> grid;
               
                  while (stmt->NextRow())
                  {      
                      std::shared_ptr<CArrayStr> rows(new CArrayStr);
               
                      // удаляем строки вида '(null)'
                      for (int k = 0; k < stmt->Fields(); ++k)
                      {
                          if (CString(stmt->ValueString(k)) != _T("(null)"))
                              rows->Add(stmt->ValueString(k));
                          else
                              rows->Add(_T(""));
                      }
                      grid.Add(rows);
                  }
               
                  /* теперь пишем в CListCtrl */
                  LVITEM lv;
                  lv.mask = LVIF_TEXT;
                  CString value, n;
                  int i = 0;
                  for (int i = 0; i < grid.GetCount(); ++i)
                  {
                      lv.iItem = i;
                      lv.iSubItem = 0;
                      n.Format(_T("%d"), i + 1);
                      lv.pszText = n.GetBuffer(n.GetLength());
                      list->InsertItem(&lv);
               
                      for (int k = 1; k < grid[i]->GetCount(); ++k)
                      {
                          lv.iSubItem = k;
                          value = stmt->ValueString(k);
                          value = (*grid[i])[k];
                          lv.pszText = value.GetBuffer(value.GetLength());
                          list->SetItem(&lv);
                      }
                  }
              }

            можно было и без него делать, но я не ищу легких путей :D
            хотя не не так я ищу легкие пути, но не легкие в плане писанины, стараюсь больше кодить :)
            Сообщение отредактировано: Cfon -
              В Java есть такая хренотень называется Hibernate, в основном нужна для того, чтобы отображать таблицы в БД в виде объектов Java. Там в XML можно наколбасить специальный такой метаобъект, из него получается класс, который по сути представляет из себя описание таблицы. Я правда с этим работал давненько, в году 2015 в последний раз. Но, тем не менее, может быть тебе сделать что то подобное? Ну типа колбасишь какой то класс, который соответствует таблице в БД, связи осуществляются путем агрегирования(вот тут подробнее про этот термин можешь почитать)
              С одной стороны да - есть небольшая проблема совместимости, т.е. если в таблице в БД добавится или удалится колонка, тогда придется править этот класс. Но с другой стороны, ты получаешь полноценный объект, с которым очень просто работать.
              Так же встречаются в некоторых АПИ такие структуры как octetsequence, допустим в древней Corba технологии такое используется, грубо говоря - это двумерный массив данных, но он нужен больше для сериализации, чем для работы с БД.
              Еще так же есть вариант создания POD объектов, очень часто такое встречается в С/С++, в данном случае под POD объектом имеется ввиду простая структура фиксированного размера.
              Т.е. вот в БД есть у тебя таблица, каждый столбик имеет ограниченный размер, например там:

              ExpandedWrap disabled
                create table users
                (
                id_user int (10) AUTO_INCREMENT,
                name varchar(20) NOT NULL,
                email varchar(50) NOT NULL,
                password varchar(15) NOT NULL,
                PRIMARY KEY (id_user)
                );

              Так вот у себя в коде ты делаешь подобную структуру:
              ExpandedWrap disabled
                struct Users
                {
                   int id_user[10]; //! Это ключевое поле PRIMARY KEY
                   char name[20];
                   char email[50];
                   char password[50];
                };


              Потом создаешь допустим вектор таких структур и забиваешь их данными из БД. Уже даже с этим проще работать. В твоем же случае ты используешь двумерный массив строк, как потом по типам их раскидывать? Наткнешься на грабли.
              Я бы делал наверное или как в Hibernate, ну или что то похожее, или через POD структуры, темболее всякие sqllite скорее всего заточены на это, т.е. скорее всего там когда тебе что то возвращается можно указывать куда писать а также сразу форматировать в разные типы данных, хотя вот конкретно с sqllite я не работал. Мне кажется так было бы проще.

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

              Добавлено
              Да, и с объектами/структурами тебе же потом проще будет делать декомпозицию, и получится проще. Потому как так ты знаешь с какой таблицей ты работаешь, а в твоем случае - двумерный массив, а что за таблица - легко можно провтыкать, и просидеть потом неделю в отладчике из за какой нибудь опечатки в коде.
              Сообщение отредактировано: KILLER -
                Цитата KILLER @
                В Java есть такая хренотень называется Hibernate, в основном нужна для того, чтобы отображать таблицы в БД в виде объектов Java. Там в XML можно наколбасить специальный такой метаобъект, из него получается класс, который по сути представляет из себя описание таблицы. Я правда с этим работал давненько, в году 2015 в последний раз. Но, тем не менее, может быть тебе сделать что то подобное? Ну типа колбасишь какой то класс, который соответствует таблице в БД, связи осуществляются путем агрегирования
                Скрытый текст
                (вот тут подробнее про этот термин можешь почитать)
                С одной стороны да - есть небольшая проблема совместимости, т.е. если в таблице в БД добавится или удалится колонка, тогда придется править этот класс. Но с другой стороны, ты получаешь полноценный объект, с которым очень просто работать.
                Так же встречаются в некоторых АПИ такие структуры как octetsequence, допустим в древней Corba технологии такое используется, грубо говоря - это двумерный массив данных, но он нужен больше для сериализации, чем для работы с БД.
                Еще так же есть вариант создания POD объектов, очень часто такое встречается в С/С++, в данном случае под POD объектом имеется ввиду простая структура фиксированного размера.
                Т.е. вот в БД есть у тебя таблица, каждый столбик имеет ограниченный размер, например там:

                ExpandedWrap disabled
                  create table users
                  (
                  id_user int (10) AUTO_INCREMENT,
                  name varchar(20) NOT NULL,
                  email varchar(50) NOT NULL,
                  password varchar(15) NOT NULL,
                  PRIMARY KEY (id_user)
                  );

                Так вот у себя в коде ты делаешь подобную структуру:
                ExpandedWrap disabled
                  struct Users
                  {
                     int id_user[10]; //! Это ключевое поле PRIMARY KEY
                     char name[20];
                     char email[50];
                     char password[50];
                  };


                Потом создаешь допустим вектор таких структур и забиваешь их данными из БД. Уже даже с этим проще работать. В твоем же случае ты используешь двумерный массив строк, как потом по типам их раскидывать? Наткнешься на грабли.
                Я бы делал наверное или как в Hibernate, ну или что то похожее, или через POD структуры, темболее всякие sqllite скорее всего заточены на это, т.е. скорее всего там когда тебе что то возвращается можно указывать куда писать а также сразу форматировать в разные типы данных, хотя вот конкретно с sqllite я не работал. Мне кажется так было бы проще.

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

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

                да вначале была такая идея про hibernate когда то читал и даже щупал :D
                но ща опробую другой стиль программирования чисто для демо т.е. пишу как есть сходу гавнокод решаю мелкие задачи в виде шажков и потом если вдруг траблы делаю рефакторинг :)
                таким образом нубы (я тоже в какой то мере нуб :D) пройдут со мной весь путь от чистого листа до готового приложения БД :)
                я надеюсь что так и будет ;)

                Добавлено
                да и возможно потом (если будет желание) попробую переделать тоже демо-приложение через технологию ORM :)

                Добавлено
                цель же этого подхода дать нубам поюзать SQL ручками, т.к. сиквел основа программирования БД :)
                Сообщение отредактировано: Cfon -
                  Цитата Cfon @
                  цель же этого подхода дать нубам поюзать SQL ручками, т.к. сиквел основа программирования БД :)

                  Ну у тебя сейчас подход - "Как делать нельзя". Делай хотя бы через POD объекты, это будет по крайней мере легче, чем у тебя сейчас. Нубы полюбому будут смотреть последнюю версию "Как правильно", а как не правильно врятли будут смотреть. Темболее что у тебя там уже с десяток зип архивов с проектами, такими апдейтами ежедневными, к концу месяца уже их наберется около 30-40 :D

                  Добавлено
                  Цитата KILLER @
                  такими апдейтами ежедневными, к концу месяца уже их наберется около 30-40 :D

                  Именно по этому я тебе в соседней теме и писал, что лучше потратить день на освоение СКВ, и делать правильно, тогда у тебя получится всегда актуальная версия, можно еще понаделать бранчей, для каких то тестовых проектов.
                  Сообщение отредактировано: KILLER -
                    Цитата Cfon @
                    typedef CArray<CString, LPCTSTR> CArrayStr;

                    Здесь, наверное, следует делать CArray<CString, const CString &>. Иначе у тебя всегда будет создаваться копия строки. А так, будет отрабатывать конструктор копирования CString, который вроде как copy-on-write

                    Добавлено
                    Цитата Cfon @
                    arrayArrays.Add(values);

                    А здесь, даже если бы скомпилировалось, то всегда создавалась бы копия массива. Оно тебе надо? У этих классов вообще, по-моему, move-конструкторов нет
                      Цитата KILLER @
                      Ну у тебя сейчас подход - "Как делать нельзя". Делай хотя бы через POD объекты, это будет по крайней мере легче, чем у тебя сейчас. Нубы полюбому будут смотреть последнюю версию "Как правильно", а как не правильно врятли будут смотреть. Темболее что у тебя там уже с десяток зип архивов с проектами, такими апдейтами ежедневными, к концу месяца уже их наберется около 30-40 :D

                      что значит нельзя? можно :)
                      это же демо, тут все можно главное результат.
                      я же говорю решаю проблемы по мере поступления если конечно они появляются ;)

                      Добавлено
                      Цитата Олег М @
                      Цитата Cfon @
                      typedef CArray<CString, LPCTSTR> CArrayStr;

                      Здесь, наверное, следует делать CArray<CString, const CString &>. Иначе у тебя всегда будет создаваться копия строки. А так, будет отрабатывать конструктор копирования CString, который вроде как copy-on-write

                      Добавлено
                      Цитата Cfon @
                      arrayArrays.Add(values);

                      А здесь, даже если бы скомпилировалось, то всегда создавалась бы копия массива. Оно тебе надо? У этих классов вообще, по-моему, move-конструкторов нет

                      да LPCTSTR по запарке пишу обычно просто CArray<CString> тот вариант вроде мне был нужен при использовании с CMap я ща не помню там с мапой простой вариант вроде не компилируется врать не буду компа нет под рукой :)
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0622 ]   [ 16 queries used ]   [ Generated: 19.04.24, 01:25 GMT ]