Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Bulgarian
  4. QVector / QList проблем при използването им със потребителски класове
Forum Updated to NodeBB v4.3 + New Features

QVector / QList проблем при използването им със потребителски класове

Scheduled Pinned Locked Moved Solved Bulgarian
qtimerconnectqtserviceqcoreapplicatio
27 Posts 2 Posters 14.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Stoyan
    28 Oct 2015, 17:26

    @pecuna91
    Какъв все пак е проблема? Не си качил променената версия и не виждам къде и как използваш triggers.

    Не би трябвало наследяването на QObject да е проблем. Но аз си мисля, че е по-добре по-сложните класове да се пазят в списъци и масиви като указатели. Така ще си спестиш и разправиите с copy конструктор и допълнителни оператори. Освен това ще избегнеш дублирането на данните.
    Но това е мое мнение. Не съм разглеждал подробно структурата на програмата ти и е по-добре сам да прецениш.

    P Offline
    P Offline
    pecuna91
    wrote on 29 Oct 2015, 10:24 last edited by
    #13

    @Stoyan
    Обновил съм хранилището.
    Дефинирах QVector < Trigger*> triggers в базовия клас понеже се усетих че и Task и Operation имат този вектор като атрибут.
    Пооптимизрах Copy конструкторите да ползват operator= за съответния клас, и да се избегне писането на един и същи код два пъти.
    Проблемът сега е с разкоментирването на
    triggers.push_back(obj);
    на 182 ред в baseobject.cpp във функцията
    int BaseObject::actionTriggers(QString Action, const Trigger *obj)

    Не ми е ясно как стоят нещата със добавянето във вектора указател към обект.

    When everything goes wrong, remember that it could be still worse...

    S 1 Reply Last reply 29 Oct 2015, 16:03
    0
    • P pecuna91
      29 Oct 2015, 10:24

      @Stoyan
      Обновил съм хранилището.
      Дефинирах QVector < Trigger*> triggers в базовия клас понеже се усетих че и Task и Operation имат този вектор като атрибут.
      Пооптимизрах Copy конструкторите да ползват operator= за съответния клас, и да се избегне писането на един и същи код два пъти.
      Проблемът сега е с разкоментирването на
      triggers.push_back(obj);
      на 182 ред в baseobject.cpp във функцията
      int BaseObject::actionTriggers(QString Action, const Trigger *obj)

      Не ми е ясно как стоят нещата със добавянето във вектора указател към обект.

      S Offline
      S Offline
      Stoyan
      wrote on 29 Oct 2015, 16:03 last edited by Stoyan
      #14

      @pecuna91
      Все още не е обновено. В baseobject.cpp в момента има само 88 реда.

      Идеята с указателите е да се дефинира например така:
      QList<Task*> tasks; // или QVector<Task*> tasks;
      (Виж в документацията на Qt в кои случаи се препоръчва използването на QList и в кои - на QVector.)
      След това зареждането на задачите ще стане така:
      Task *newtask = new Task();
      newtask->setName(propelement.attribute("name"));
      tasks.append(newtask); // или tasks.push_back(newtask);

      Използването на tasks става така:
      QString taskname = tasks.at(i)->getName(); // или tasks[i]->getName();

      В момента използваш copy конструктор, но не изтриваш междинните обекти, които си създал с Task *newtask = new Task(); и те си остават в паметта.
      Ако остане както досега, ще трябва да ги изтриеш с delete newtask;
      Ако се използва списък с указатели, не трябва да ги изтриваш след добавяне, а чак когато се изтриват (премахват) от списъка.

      P 1 Reply Last reply 29 Oct 2015, 17:48
      1
      • S Stoyan
        29 Oct 2015, 16:03

        @pecuna91
        Все още не е обновено. В baseobject.cpp в момента има само 88 реда.

        Идеята с указателите е да се дефинира например така:
        QList<Task*> tasks; // или QVector<Task*> tasks;
        (Виж в документацията на Qt в кои случаи се препоръчва използването на QList и в кои - на QVector.)
        След това зареждането на задачите ще стане така:
        Task *newtask = new Task();
        newtask->setName(propelement.attribute("name"));
        tasks.append(newtask); // или tasks.push_back(newtask);

        Използването на tasks става така:
        QString taskname = tasks.at(i)->getName(); // или tasks[i]->getName();

        В момента използваш copy конструктор, но не изтриваш междинните обекти, които си създал с Task *newtask = new Task(); и те си остават в паметта.
        Ако остане както досега, ще трябва да ги изтриеш с delete newtask;
        Ако се използва списък с указатели, не трябва да ги изтриваш след добавяне, а чак когато се изтриват (премахват) от списъка.

        P Offline
        P Offline
        pecuna91
        wrote on 29 Oct 2015, 17:48 last edited by
        #15

        @Stoyan
        Хмм, обнових го наново.
        Значи по дебъг логването в конзолата виждам, че се вика Task Destructor след като се излиза от функцията, така че явно обекта се самоизтрива.
        Идеята ми е евентуално тригерите да са във вектор/списък от указатели, понеже се предполага че те ще са най-много на брой.
        Но как ще стане тяхното използване? Сега съм направил и класът Trigger да наследява и Runnable.
        Идеята ми е как трябва да е дефинирана функцията void setTrigger(const Trigger &obj) , за да може в нея да се сетва/делийтва тригер от вектора/списъка? И след това как ще се подава аргумента
        tasks.at(k).setTrigger(obj) ли?

        When everything goes wrong, remember that it could be still worse...

        S 1 Reply Last reply 29 Oct 2015, 19:46
        0
        • P pecuna91
          29 Oct 2015, 17:48

          @Stoyan
          Хмм, обнових го наново.
          Значи по дебъг логването в конзолата виждам, че се вика Task Destructor след като се излиза от функцията, така че явно обекта се самоизтрива.
          Идеята ми е евентуално тригерите да са във вектор/списък от указатели, понеже се предполага че те ще са най-много на брой.
          Но как ще стане тяхното използване? Сега съм направил и класът Trigger да наследява и Runnable.
          Идеята ми е как трябва да е дефинирана функцията void setTrigger(const Trigger &obj) , за да може в нея да се сетва/делийтва тригер от вектора/списъка? И след това как ще се подава аргумента
          tasks.at(k).setTrigger(obj) ли?

          S Offline
          S Offline
          Stoyan
          wrote on 29 Oct 2015, 19:46 last edited by
          #16

          @pecuna91
          Да. Така, както си го променил се изтрива, защото вече само го дефинираш. Така създаденият обект се унищожава щом програмата излезе извън блока, в който е дефиниран. Преди ги създаваше с new и тогава не се изтриваха.

          Не мога да разбера връзката между Task, Operation и Trigger. Изглежда, че всяка задача има по няколко операции, а всяка операция съдържа по няколко тригера, но последното не виждам да си го дефинирал никъде. Къде трябва да се четат и задават тригерите?

          Имам едно предложение. За времето на разработката изключи използването на service и разглеждай програмата като обикновено конзолно приложение. Така е много по-лесно за debug-ване. Когато се увериш, че всичко работи както трябва, лесно можеш да я пуснеш като service отново.
          Това става лесно. Направи main() да изглежда така:
          int main(int argc, char *argv[])
          {
          QCoreApplication app(argc, argv);
          GUIServer *guiserver;
          qDebug() << "\n\tService started!";
          if (QSslSocket::supportsSsl())
          {
          qDebug() << "\tSSL is supported";
          }
          else
          {
          qDebug() << "\tSSL is not supported! \n\tCheck if Openssl libraries are present.";
          }
          guiserver = new GUIServer();
          guiserver->StartServer(QString(globalVars.getOption("Server Port")).toInt());
          QString s = "password123";
          QByteArray hash384 = QCryptographicHash::hash(s.toLocal8Bit(),QCryptographicHash::Sha3_384);
          qDebug() << "HASH 3_384: " << hash384.toHex();
          if (!guiserver->getServerrunning())
          {
          qDebug() <<"\n\tExiting Service.";
          return 1;
          }
          app.exec();
          }

          P 1 Reply Last reply 29 Oct 2015, 20:14
          0
          • S Stoyan
            29 Oct 2015, 19:46

            @pecuna91
            Да. Така, както си го променил се изтрива, защото вече само го дефинираш. Така създаденият обект се унищожава щом програмата излезе извън блока, в който е дефиниран. Преди ги създаваше с new и тогава не се изтриваха.

            Не мога да разбера връзката между Task, Operation и Trigger. Изглежда, че всяка задача има по няколко операции, а всяка операция съдържа по няколко тригера, но последното не виждам да си го дефинирал никъде. Къде трябва да се четат и задават тригерите?

            Имам едно предложение. За времето на разработката изключи използването на service и разглеждай програмата като обикновено конзолно приложение. Така е много по-лесно за debug-ване. Когато се увериш, че всичко работи както трябва, лесно можеш да я пуснеш като service отново.
            Това става лесно. Направи main() да изглежда така:
            int main(int argc, char *argv[])
            {
            QCoreApplication app(argc, argv);
            GUIServer *guiserver;
            qDebug() << "\n\tService started!";
            if (QSslSocket::supportsSsl())
            {
            qDebug() << "\tSSL is supported";
            }
            else
            {
            qDebug() << "\tSSL is not supported! \n\tCheck if Openssl libraries are present.";
            }
            guiserver = new GUIServer();
            guiserver->StartServer(QString(globalVars.getOption("Server Port")).toInt());
            QString s = "password123";
            QByteArray hash384 = QCryptographicHash::hash(s.toLocal8Bit(),QCryptographicHash::Sha3_384);
            qDebug() << "HASH 3_384: " << hash384.toHex();
            if (!guiserver->getServerrunning())
            {
            qDebug() <<"\n\tExiting Service.";
            return 1;
            }
            app.exec();
            }

            P Offline
            P Offline
            pecuna91
            wrote on 29 Oct 2015, 20:14 last edited by pecuna91
            #17

            @Stoyan said:

            Не мога да разбера връзката между Task, Operation и Trigger. Изглежда, че всяка задача има по няколко операции, а всяка операция съдържа по няколко тригера, но последното не виждам да си го дефинирал никъде. Къде трябва да се четат и задават тригерите?

            Всяка задача и операция има вектор от тригери, които могат да я стартират впоследствие. Задават се във всеки обект при зареждането му, като трябва да могат и да се променят във всяко едно време от клиентската част. През определен период от време се проверяват тригерите и ако условието е изпълнено връща ок за изпълнение на задачата/операцията.
            Най-вероятно ще ми трябва Scheduler да бъде наследник на QOBject за да мога да ползвам connect, но нещо пак не иска.

            scheduler.cpp:-1: error: undefined reference to `vtable for Scheduler'
            

            Добавил съм Q_OBJECT Макрото и промених конструктора.

            Програмата се стартира като конзолно приложение с добавяне на
            -e
            в Run arguments .
            Каква е разликата с нормална конзолна програма и сървис с -е ?

            When everything goes wrong, remember that it could be still worse...

            S 1 Reply Last reply 30 Oct 2015, 00:17
            0
            • P pecuna91
              29 Oct 2015, 20:14

              @Stoyan said:

              Не мога да разбера връзката между Task, Operation и Trigger. Изглежда, че всяка задача има по няколко операции, а всяка операция съдържа по няколко тригера, но последното не виждам да си го дефинирал никъде. Къде трябва да се четат и задават тригерите?

              Всяка задача и операция има вектор от тригери, които могат да я стартират впоследствие. Задават се във всеки обект при зареждането му, като трябва да могат и да се променят във всяко едно време от клиентската част. През определен период от време се проверяват тригерите и ако условието е изпълнено връща ок за изпълнение на задачата/операцията.
              Най-вероятно ще ми трябва Scheduler да бъде наследник на QOBject за да мога да ползвам connect, но нещо пак не иска.

              scheduler.cpp:-1: error: undefined reference to `vtable for Scheduler'
              

              Добавил съм Q_OBJECT Макрото и промених конструктора.

              Програмата се стартира като конзолно приложение с добавяне на
              -e
              в Run arguments .
              Каква е разликата с нормална конзолна програма и сървис с -е ?

              S Offline
              S Offline
              Stoyan
              wrote on 30 Oct 2015, 00:17 last edited by Stoyan
              #18

              @pecuna91
              Тази грешка се появява когато си добавил макроса Q_OBJECT. При компилирането не се е изпълнила командата qmake, както би трябвало. Трябва да я пуснеш ръчно като цъкнеш с десен бутон на проекта и избереш "Run qmake". При мен така се компилира.

              По принцип не би трябвало да има разлика, ако се пусне и като service с аргумент "-e", но при мен така даде грешка:
              The service could not be executed. ()
              can't find linker symbol for virtual table for `Service' value
              Когато преместих съдържанието на функцията start() в main(), както ти писах, тръгна и даде такъв резултат:
              SSL is supported
              Server Listening on port: 1234
              "stopped"
              Task is disabled
              "stopped"
              Task is disabled
              ....

              Предполагам, че има някакъв проблем при свързването с външната библиотека за поддръжка на service.
              Преди време правих една програма, която трябваше да работи като service и използвах ето този компонент:
              https://github.com/qtproject/qt-solutions/tree/master/qtservice
              Ако го добавиш като подпроект няма да има нужда от външни библиотеки, защото се включва в изпълнимия файл.

              P 1 Reply Last reply 30 Oct 2015, 05:39
              1
              • S Stoyan
                30 Oct 2015, 00:17

                @pecuna91
                Тази грешка се появява когато си добавил макроса Q_OBJECT. При компилирането не се е изпълнила командата qmake, както би трябвало. Трябва да я пуснеш ръчно като цъкнеш с десен бутон на проекта и избереш "Run qmake". При мен така се компилира.

                По принцип не би трябвало да има разлика, ако се пусне и като service с аргумент "-e", но при мен така даде грешка:
                The service could not be executed. ()
                can't find linker symbol for virtual table for `Service' value
                Когато преместих съдържанието на функцията start() в main(), както ти писах, тръгна и даде такъв резултат:
                SSL is supported
                Server Listening on port: 1234
                "stopped"
                Task is disabled
                "stopped"
                Task is disabled
                ....

                Предполагам, че има някакъв проблем при свързването с външната библиотека за поддръжка на service.
                Преди време правих една програма, която трябваше да работи като service и използвах ето този компонент:
                https://github.com/qtproject/qt-solutions/tree/master/qtservice
                Ако го добавиш като подпроект няма да има нужда от външни библиотеки, защото се включва в изпълнимия файл.

                P Offline
                P Offline
                pecuna91
                wrote on 30 Oct 2015, 05:39 last edited by pecuna91
                #19

                @Stoyan
                АБсолютния същия проект ползвам. Можеш да видиш QtService папката във сорсовете. Библиотеката съм я добавил за да нямам допълнителни cpp файлове и да се компилира по-бързо програмата. Добавил ли си
                QtSolutions_Service-head.dll файла в release директорията?

                Благодаря за "run qmake", досега каквото съм добавял и правил наследник на QObject винаги е тръгвало без ръчно изпълнение на тази команда.
                Успеях да преместя таймера при сървис класа.
                Остава въпросът как точно ще се пушват новите тригери във вектора на обекта.
                Успях да го направя , но искам да е с копи конструктор или оператор = , a не с функция setAll(const Trigger &obj), което е същото де.

                When everything goes wrong, remember that it could be still worse...

                S 1 Reply Last reply 30 Oct 2015, 11:47
                0
                • P pecuna91
                  30 Oct 2015, 05:39

                  @Stoyan
                  АБсолютния същия проект ползвам. Можеш да видиш QtService папката във сорсовете. Библиотеката съм я добавил за да нямам допълнителни cpp файлове и да се компилира по-бързо програмата. Добавил ли си
                  QtSolutions_Service-head.dll файла в release директорията?

                  Благодаря за "run qmake", досега каквото съм добавял и правил наследник на QObject винаги е тръгвало без ръчно изпълнение на тази команда.
                  Успеях да преместя таймера при сървис класа.
                  Остава въпросът как точно ще се пушват новите тригери във вектора на обекта.
                  Успях да го направя , но искам да е с копи конструктор или оператор = , a не с функция setAll(const Trigger &obj), което е същото де.

                  S Offline
                  S Offline
                  Stoyan
                  wrote on 30 Oct 2015, 11:47 last edited by Stoyan
                  #20

                  @pecuna91
                  Даваше грешка, само когато се компилира в Debug режим. В Release работи. Предполагам, защото във файла на проекта си задал винаги да се зарежда библиотеката QtSolutions_Service-head.dll, която е за Release. При компилиране за Debug трябва да се зарежда библиотеката QtSolutions_Service-headd.dll.

                  Доколкото виждам зареждането на тригерите става с функциите loadOperationTrigger() и loadTaskTrigger(), а добавянето в съответната задача или операция - с BaseObject::actionTriggers(QString Action, const Trigger &obj).
                  Ако се използва списък с указатели, аз предлагам последната функция да стане:
                  int BaseObject::actionTriggers(QString Action, Trigger *obj)
                  а още по-добре е да я разделиш на две функции:
                  {
                  addTrigger(Trigger * trigger);
                  delTrigger(Trigger * trigger);
                  В тях се включва:
                  triggers.append(trigger); // в addTrigger() - добавя указания тригер в списъка на текущия обект (Task или Operation)
                  triggers.removeAll(trigger); // в delTrigger() - премахва указания тригер от списъка на обекта.
                  После ги извикваш така:
                  Trigger * trigger;
                  trigger = new Trigger();
                  trigger->id = ...;
                  trigger->type = ...;
                  ...
                  task.addTrigger(trigger); // или operation.addTrigger(trigger);

                  P 1 Reply Last reply 30 Oct 2015, 14:13
                  0
                  • S Stoyan
                    30 Oct 2015, 11:47

                    @pecuna91
                    Даваше грешка, само когато се компилира в Debug режим. В Release работи. Предполагам, защото във файла на проекта си задал винаги да се зарежда библиотеката QtSolutions_Service-head.dll, която е за Release. При компилиране за Debug трябва да се зарежда библиотеката QtSolutions_Service-headd.dll.

                    Доколкото виждам зареждането на тригерите става с функциите loadOperationTrigger() и loadTaskTrigger(), а добавянето в съответната задача или операция - с BaseObject::actionTriggers(QString Action, const Trigger &obj).
                    Ако се използва списък с указатели, аз предлагам последната функция да стане:
                    int BaseObject::actionTriggers(QString Action, Trigger *obj)
                    а още по-добре е да я разделиш на две функции:
                    {
                    addTrigger(Trigger * trigger);
                    delTrigger(Trigger * trigger);
                    В тях се включва:
                    triggers.append(trigger); // в addTrigger() - добавя указания тригер в списъка на текущия обект (Task или Operation)
                    triggers.removeAll(trigger); // в delTrigger() - премахва указания тригер от списъка на обекта.
                    После ги извикваш така:
                    Trigger * trigger;
                    trigger = new Trigger();
                    trigger->id = ...;
                    trigger->type = ...;
                    ...
                    task.addTrigger(trigger); // или operation.addTrigger(trigger);

                    P Offline
                    P Offline
                    pecuna91
                    wrote on 30 Oct 2015, 14:13 last edited by pecuna91
                    #21

                    @Stoyan
                    По този начин сетвам тригерите да.
                    Функцията искам да е една, еднотипна за всичките обекти.
                    Проблемът сега се явява отново Segmentation fault при извикване на get някой атрибут на тригер извън globalvars класа. Например в servicе или Scheduler. Понеже понякога /в редки случаи/ не го дава предполагам че е отново реда на създаване на обектите и сетването им. Можеби ще трябва да въведа някакви паузи докато се инициализират нещата,
                    Интересното е че не излизат атрибутите на тригерите когато ги викам с гетерите в друг клас извън GlobalVars и гърми с грешката.

                    When everything goes wrong, remember that it could be still worse...

                    S 1 Reply Last reply 30 Oct 2015, 16:45
                    0
                    • P pecuna91
                      30 Oct 2015, 14:13

                      @Stoyan
                      По този начин сетвам тригерите да.
                      Функцията искам да е една, еднотипна за всичките обекти.
                      Проблемът сега се явява отново Segmentation fault при извикване на get някой атрибут на тригер извън globalvars класа. Например в servicе или Scheduler. Понеже понякога /в редки случаи/ не го дава предполагам че е отново реда на създаване на обектите и сетването им. Можеби ще трябва да въведа някакви паузи докато се инициализират нещата,
                      Интересното е че не излизат атрибутите на тригерите когато ги викам с гетерите в друг клас извън GlobalVars и гърми с грешката.

                      S Offline
                      S Offline
                      Stoyan
                      wrote on 30 Oct 2015, 16:45 last edited by Stoyan
                      #22

                      BaseObject::actionTriggers в момента изпълнява две съвсем различни неща и ще бъде по-ясно ако ги разделиш в отделни функции, но естествено не е задължително. А функциите, които предложих addTrigger() и delTrigger() пак са в основния клас и са едни и същи и за задачите и за операциите.

                      А за грешките - ще трябва да качиш промените, за да видя какви са и как се получават.

                      P 1 Reply Last reply 30 Oct 2015, 18:17
                      0
                      • S Stoyan
                        30 Oct 2015, 16:45

                        BaseObject::actionTriggers в момента изпълнява две съвсем различни неща и ще бъде по-ясно ако ги разделиш в отделни функции, но естествено не е задължително. А функциите, които предложих addTrigger() и delTrigger() пак са в основния клас и са едни и същи и за задачите и за операциите.

                        А за грешките - ще трябва да качиш промените, за да видя какви са и как се получават.

                        P Offline
                        P Offline
                        pecuna91
                        wrote on 30 Oct 2015, 18:17 last edited by pecuna91
                        #23

                        @Stoyan

                        Качих промените. Намалил съм дебъг логването.
                        Както ще видиш проблемът се появява когато се вика triggers.at(n).getНещоси от Scheduler класа 10 секунди след като се е стартирало приложението.

                        When everything goes wrong, remember that it could be still worse...

                        S 1 Reply Last reply 30 Oct 2015, 19:22
                        0
                        • P pecuna91
                          30 Oct 2015, 18:17

                          @Stoyan

                          Качих промените. Намалил съм дебъг логването.
                          Както ще видиш проблемът се появява когато се вика triggers.at(n).getНещоси от Scheduler класа 10 секунди след като се е стартирало приложението.

                          S Offline
                          S Offline
                          Stoyan
                          wrote on 30 Oct 2015, 19:22 last edited by Stoyan
                          #24

                          @pecuna91
                          Трябва да махнеш от BaseObject::actionTriggers

                          newtrigger->deleteLater();

                          С него първо добавяш тригера към вектора и веднага след това го изтриваш.
                          Ето какво се получи без него:

                          Service started!
                          SSL is supported
                          Server Listening on port: 1234
                          "stopped"
                          Task is disabled
                          activating task: "Task 2"
                          Trigger: "time"
                          "stopped"
                          Task is disabled
                          activating task: "Task 2"
                          Trigger: "time"
                          ....

                          Освен това, защо ти е това Trigger::operator =()? Не можеш ли командите в него да ги изпълниш директно във функцията Trigger::setAll()?
                          При начина, по който ги използваш в момента, всичките "operator =()" са излишни. И за Trigger, и за Task, и за Operation.

                          P 1 Reply Last reply 30 Oct 2015, 19:44
                          0
                          • S Stoyan
                            30 Oct 2015, 19:22

                            @pecuna91
                            Трябва да махнеш от BaseObject::actionTriggers

                            newtrigger->deleteLater();

                            С него първо добавяш тригера към вектора и веднага след това го изтриваш.
                            Ето какво се получи без него:

                            Service started!
                            SSL is supported
                            Server Listening on port: 1234
                            "stopped"
                            Task is disabled
                            activating task: "Task 2"
                            Trigger: "time"
                            "stopped"
                            Task is disabled
                            activating task: "Task 2"
                            Trigger: "time"
                            ....

                            Освен това, защо ти е това Trigger::operator =()? Не можеш ли командите в него да ги изпълниш директно във функцията Trigger::setAll()?
                            При начина, по който ги използваш в момента, всичките "operator =()" са излишни. И за Trigger, и за Task, и за Operation.

                            P Offline
                            P Offline
                            pecuna91
                            wrote on 30 Oct 2015, 19:44 last edited by pecuna91
                            #25

                            @Stoyan
                            Хмм, хем ми направи впечетление за тоя Delete later още на сокетите че го казаха в туториала че прави проблем и го сложих...
                            Махнах оператор= за тригера, но ми направи впечетление че Copy constructor-а трябва да си стои като дефиниция поне иначе гърми с грешки, но защо изобщо трябва да е дефиниран , но не и реално имплентиран?

                            When everything goes wrong, remember that it could be still worse...

                            S 1 Reply Last reply 31 Oct 2015, 00:03
                            0
                            • P pecuna91
                              30 Oct 2015, 19:44

                              @Stoyan
                              Хмм, хем ми направи впечетление за тоя Delete later още на сокетите че го казаха в туториала че прави проблем и го сложих...
                              Махнах оператор= за тригера, но ми направи впечетление че Copy constructor-а трябва да си стои като дефиниция поне иначе гърми с грешки, но защо изобщо трябва да е дефиниран , но не и реално имплентиран?

                              S Offline
                              S Offline
                              Stoyan
                              wrote on 31 Oct 2015, 00:03 last edited by
                              #26

                              @pecuna91
                              Не бих казал, че deleteLater() прави проблеми. Понякога дори не може без него. Просто в този случай не прави това, което си си мислел, че прави.

                              Trigger *newtrigger = new Trigger(); // създава се нов обект Trigger като newtrigger е указател към него
                              newtrigger->setAll(obj); // задават се всички параметри за тригера
                              newtrigger->deleteLater(); // изтрива се обекта, към който сочи указателя
                              triggers.push_back(newtrigger); // добавя се указателя към тригера във вектора

                              Когато по-късно използваш triggers.at(i) всъщност взимаш указателя от вектора, но той вече сочи към случаен адрес в паметта. Затова и гърми.
                              Но когато изтриваш тригер от вектора ще трябва да използваш delete() или deleteLater().

                              Copy constructor-а за Trigger всъщност се използва неявно във функцията GlobalVars::loadTrigger(). Затова и не можеш да го махнеш.

                              P 1 Reply Last reply 1 Nov 2015, 18:49
                              1
                              • S Stoyan
                                31 Oct 2015, 00:03

                                @pecuna91
                                Не бих казал, че deleteLater() прави проблеми. Понякога дори не може без него. Просто в този случай не прави това, което си си мислел, че прави.

                                Trigger *newtrigger = new Trigger(); // създава се нов обект Trigger като newtrigger е указател към него
                                newtrigger->setAll(obj); // задават се всички параметри за тригера
                                newtrigger->deleteLater(); // изтрива се обекта, към който сочи указателя
                                triggers.push_back(newtrigger); // добавя се указателя към тригера във вектора

                                Когато по-късно използваш triggers.at(i) всъщност взимаш указателя от вектора, но той вече сочи към случаен адрес в паметта. Затова и гърми.
                                Но когато изтриваш тригер от вектора ще трябва да използваш delete() или deleteLater().

                                Copy constructor-а за Trigger всъщност се използва неявно във функцията GlobalVars::loadTrigger(). Затова и не можеш да го махнеш.

                                P Offline
                                P Offline
                                pecuna91
                                wrote on 1 Nov 2015, 18:49 last edited by pecuna91 11 Feb 2015, 15:51
                                #27

                                @Stoyan
                                error: passing 'const Operation' as 'this' argument of 'int Operation::setAttribute(QString, QString)' discards qualifiers [-fpermissive]
                                operations.at(i).setAttribute(Aname,Value);

                                Не мога да разбера защо се получава това съобщение в Task класа, опитвайки се да извикам метода SetAttribute за операция във вектора.
                                Const Operation не знам откъде идва вътре в тази функция конкретно, след като подавам само id-то на операцията.
                                Подобна е грешката и при Task сетване на атрибут:
                                scheduledtopservice\scheduler.cpp:31: error: passing 'const Task' as 'this' argument of 'int Task::setAttribute(QString, QString)' discards qualifiers [-fpermissive]
                                tasks.at(k).setAttribute("state","running");

                                ПП:
                                Успях да го реша проблема. Разбрах че .at() връща const обект, затова използвах [i] за индекс.

                                task.cpp:17: warning: base class 'class BaseObject' should be explicitly initialized in the copy constructor [-Wextra]
                                Task::Task(const Task &obj)
                                Това как мога да го оправя, четох че създавало още 1 копие на BaseObject така. Но не е като експлицитния конструктор сякаш : BaseObject ( const BaseObject &obj) ако долепя до Copy конструктора на Task. Не съм сигурен, но май просто като сложих : BaseObject() и се изчисти предупреждението. Така ли трябвa да бъде ?

                                When everything goes wrong, remember that it could be still worse...

                                1 Reply Last reply
                                0

                                22/27

                                30 Oct 2015, 16:45

                                • Login

                                • Login or register to search.
                                22 out of 27
                                • First post
                                  22/27
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved