На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> TStrings -> TStringList
    Есть список строк, который имеет тип TStrings (OpenDialog->Files) и функция, в которую передаются списки строк типа TStringList. Как можно передать в эту функцию OpenDialog->Files? Комилятор на строку с передачей OpenDialog->Files ругается: Cannot convert 'TStrings * const' to 'TStringList *'.
      ExpandedWrap disabled
            TStringList *a = new TStringList;
            OpenDialog1->Execute();
            a = (TStringList*)(OpenDialog1->Files);
            ShowMessage(a->Text);


      т.е. просто даем знать что адрес у нас именно TStringList. Но стоит учитывать что как только уничтожится объект OpenDialog1 уничтожится и ссылка хранящаяся в OpenDialog1->Files и в переменной по адресу a можно уже ничего и не обнаружить... потому лучше было бы использовать такой вариант

      ExpandedWrap disabled
            TStringList *a = new TStringList;
            OpenDialog1->Execute();
            a->Text = OpenDialog1->Files->Text;
            ShowMessage(a->Text);


      а вообще как я понял используется только текст потому можно использовать просто AnsiString ;)

      ExpandedWrap disabled
            OpenDialog1->Execute();
            AnsiString *a = new AnsiString;
            *a = OpenDialog1->Files->Text;
            ShowMessage(*a);
        Это - демка. На самом деле lst надо создать, например, в FormCreate, а уничтожить в FormClose
        ExpandedWrap disabled
          void __fastcall TForm1::Button1Click(TObject *Sender) {
            TStringList *lst = new TStringList();
            if (OpenDialog1->Execute())
              lst->Assign(OpenDialog1->Files);
            delete lst;
          }
          Цитата Coala @
          Это - демка. На самом деле lst надо создать, например, в FormCreate, а уничтожить в FormClose
          Да не обязательно. Если только в этом месте используется, то лучше как у тебя в коде.
            Unicorn, cпасибо. А еще ради интереса хотел узнать, какая разница между TStringList и TStrings? - обое хранят списки строк, но разница в чемто должна быть.
            Цитата
            а вообще как я понял используется только текст потому можно использовать просто AnsiString

            А если в StringList большое количество строк, как же программа будет работать с такой длинной строкой? Такой подход чем-то лучше? Я иногда использую такую возможность, но не всегда.
            Coala, Adil, а что значит "демка"?
              Цитата Shad0FF @
              А еще ради интереса хотел узнать, какая разница между TStringList и TStrings? - обое хранят списки строк, но разница в чемто должна быть.

              А ты в справку-то загляни! ;) Кратко - класс TStrings в иерархии находится выше, чем TStringList и является абстрактным. Подробно - в справке. :whistle:
                BreakPointMAN, кажется понятно. Но непонятно, что Coala хотел сказать в своем посте.
                  демка - демонстрация, пример.
                    Цитата Shad0FF @
                    Но непонятно, что Coala хотел сказать в своем посте.
                    Демонстрационный пример использования метода Assign для записи списка файлов из TOpenDialog в TStringList, неужели даже такое надо разжёвывать :wacko:
                      Coala, kalexs_uzb, понял. Всем спасибо за помощь.
                      P.S. помоему этот вариант не лучший выход, т.к. требует объявления TStringList, а зачем лишние усилия, если можно сделать как подсказал Unicorn во втором посте.
                        Shad0FF
                        Цитата
                        а зачем лишние усилия, если можно сделать как подсказал Unicorn во втором посте

                        во-первых, то что предложил Unicorn не иначе как "грязным хаком" не назовешь (это не оскорбления, а вполне устоявшийся термин :))
                        во-вторых, там у него память утекает, так что сначала ошибку исправь

                        P.S.
                        считать объявление переменной "лишними усилиями" - это круто, мельчают программисты :)
                        Сообщение отредактировано: artalex -
                          artalex, а где там утечка памяти? В том, что он забыл delete a; написать? Это же поправимо.
                            Цитата artalex @
                            считать объявление переменной "лишними усилиями" - это круто, мельчают программисты
                            Наоборот - малы ещё для серьёзных дел. Подрастут - поймут :yes:
                              Shad0FF
                              Цитата
                              а где там утечка памяти?

                              ExpandedWrap disabled
                                TStringList *a = new TStringList; // выделяем память под объект, эта строка вообще лишняя
                                OpenDialog1->Execute();
                                a = (TStringList*)(OpenDialog1->Files); // теряем указатель на ранее выделенную память
                                ShowMessage(a->Text);

                              самое интересное будет, если функция, которой ты передаешь указатель a, захочет вызывать какой-нибуль метод специфичный для TStringList или установить/прочитать какое-нибудь свойство специфичное для TStringList, например Sorted.

                              Добавлено
                              Я тут проект маленький наваял. Вкратце, что там происходит.
                              Есть функция
                              ExpandedWrap disabled
                                void __fastcall TForm1::workWithTStringList( TStringList * aStringList ){
                                   aStringList->Sort();
                                }

                              На форме есть ListBox1 (TListBox), при нажатии кнопки вызывается workWithTStringList()
                              ExpandedWrap disabled
                                void __fastcall TForm1::Button1Click(TObject *Sender){
                                   workWithTStringList( (TStringList * )ListBox1->Items );
                                }

                              У меня стабильно выдает AV.

                              Способ который предложил Unicorn можно использовать тогда, когда происходит нечто следующее
                              ExpandedWrap disabled
                                class MyClass{
                                   public:
                                      __fastcall MyClass(){
                                         FStrings = new TStringList();
                                      }
                                      __fastcall ~MyClass(){
                                         delete FStrings;
                                      }
                                 
                                      __property TStrings * Strings = { read = FStrings };
                                 
                                   private:
                                      TStrings * FStrings;
                                };

                              в этом случае можно безболезнено делать так
                              ExpandedWrap disabled
                                MyClass * myClass;
                                ...
                                workWithTStringList( (TStringList * )myClass->Strings );

                              т.к. свойство Strings файктически является объектом TStringList, но даже в этом случае это не желательно, т.к. программист проектировавший класс возможно с каким-то умыслом сделал свойство Strings типом TStrings.

                              Единственно правильный способ для всех вышеперечисленных случаев
                              ExpandedWrap disabled
                                MyClass * myClass;
                                ...
                                TStringList * list = new TStringList();
                                try{
                                   list->Assign( myClass->Strings );
                                   workWithTStringList( (TStringList * )myClass->Strings );}
                                   myClass->Strings->Assign( list );
                                __finally{
                                   delete list;
                                }

                              на первый взгляд кажется громоздким, но гарантирует отсутствие проблем, на поиск которых в дальнейшем потратишь несколько дней, эти же строки я написал за несколько секунд.
                              Сообщение отредактировано: artalex -

                              Прикреплённый файлПрикреплённый файлTStringList.zip (3.95 Кбайт, скачиваний: 116)
                                artalex, со всем сказанным согласен, вот только workWithTStringList( (TStringList * )myClass->Strings );}
                                ты забыл поменять на workWithTStringList( list );} ;)

                                Добавлено
                                P.S. от громоздкости, кстати, лекго избавиться при помощи умного указателя:
                                ExpandedWrap disabled
                                  MyClass * myClass;
                                  ...
                                     std::auto_ptr<TStringList> list( new TStringList );
                                     list->Assign( myClass->Strings );
                                     workWithTStringList( list.get() );
                                     myClass->Strings->Assign( list.get() );
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.0878 ]   [ 15 queries used ]   [ Generated: 25.06.26, 14:17 GMT ]