Russian Qt Forum
Ноябрь 24, 2024, 02:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как правильно передать массив классов в конструктор?  (Прочитано 10516 раз)
labview
Гость
« : Август 13, 2010, 15:26 »

Всем привет!

Хочу передать один определённый массив классов в конструкторы двух других классов. Сделал так.

Класс первый:

Код:
#ifndef THREAD1_H
#define THREAD1_H

#include <QThread>

#include "Tasking.h"

class Thread1 : public QThread
{
    Q_OBJECT

public:
    Thread1(Tasking *allTasks[], int tasksCount);
private:
    virtual void run();
    Tasking *Tasks[];
signals:
    void showData(QString data);
};

#endif // THREAD1_H

Код:
#include "thread1.h"


Thread1::Thread1(Tasking *allTasks[], int tasksCount)
{
    for(int i = 0; i < tasksCount; i++)
    Tasks[i] = allTasks[i];
}

void Thread1::run()
{
    task myTask;
    myTask.tasknum = 1;
    myTask.data = "something";
    Tasks[0]->addTask(myTask);
    emit showData(myTask.data);
}

И аналогично Класс второй:
Код:
#ifndef THREAD2_H
#define THREAD2_H

#include <QThread>

#include "Tasking.h"

class Thread2 : public QThread
{
    Q_OBJECT

public:
    Thread2(Tasking *allTasks[], int tasksCount);
private:
    virtual void run();
    Tasking *Tasks[];
signals:
    void showData(QString data);
};

#endif // THREAD2_H

Код:
#include "thread2.h"

Thread2::Thread2(Tasking *allTasks[], int tasksCount)
{
    for(int i = 0; i < tasksCount; i++)
    Tasks[i] = allTasks[i];
}

void Thread2::run()
{
    task myTask;
    myTask = Tasks[0]->getTask();
    emit showData("Thread2");
}

В main.cpp делаю так:

Код:
#include <QtGui/QApplication>

#include "mainwidget.h"
#include "Tasking.h"
#include "thread1.h"
#include "thread2.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w;
    w.show();

    Tasking *allTasks[1];

    Tasking *tasking1 = new Tasking;
    allTasks[0] = tasking1;
    Thread1 myThread1(allTasks, sizeof(allTasks));
    Thread2 myThread2(allTasks, sizeof(allTasks));

    QObject::connect(&myThread1, SIGNAL(showData(QString)), &w, SLOT(addText(QString)));
    QObject::connect(&myThread2, SIGNAL(showData(QString)), &w, SLOT(addText(QString)));

    myThread1.start();
    myThread2.start();
    myThread1.wait();
    myThread2.wait();

    return a.exec();
}

Если я проделываю это только с одним классом то всё ок, а если работают оба то получаю сегфолт.

Дело вот в этой строке конструктора второго класса:
Код:
    Tasks[i] = allTasks[i];

Если эту строку убрать, то прога работает.

Подскажите плиз в чём проблема.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #1 : Август 13, 2010, 16:05 »

Может нужно вначале (перед использованием массива Tasks) выделить для него память?
Код
C++ (Qt)
   Tasks = new Tasking*[tasksCount];
 
а уже потом пытаться в него записывать.

Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
labview
Гость
« Ответ #2 : Август 13, 2010, 16:14 »

Спасибо, теперь понятно, что нужно сначала выделить память, но компилятор ругается.
Код:
 incompatible types in assignment of 'Tasking**' to 'Tasking* [0]' 

И ещё вопрос, а почему оно работало с одним классом?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Август 13, 2010, 16:17 »

1) Если Вы хотите скопировать массив указателей, то память для приемника (куда копируется) должна быть выделена напр
Код
C++ (Qt)
Thread2::Thread2(Tasking *allTasks[], int tasksCount)
{
   delete [] Tasks;                               // не забыть обнулить Tasks в конструкторе
   Tasks = new Tasking * [tasksCount];
   for(int i = 0; i < tasksCount; i++)
    Tasks[i] = allTasks[i];
}


2)
Код:
Thread1 myThread1(allTasks, sizeof(allTasks));

sizeof возвращает размер структуры в байтах, а не число элементов в массиве. Есть классная макруха

Код
C++ (Qt)
#define ITEMCOUNT(a) (sizeof(a) / sizeof(a[0]))
 
« Последнее редактирование: Август 13, 2010, 16:30 от Igors » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Август 13, 2010, 16:27 »

Спасибо, теперь понятно, что нужно сначала выделить память, но компилятор ругается.
Код:
 incompatible types in assignment of 'Tasking**' to 'Tasking* [0]' 
Что такое Tasking* []' - во всяком случае мудрено понять  Улыбающийся
Объявите проще: Tasking ** Tasks;
Записан
labview
Гость
« Ответ #5 : Август 13, 2010, 16:33 »

Ок, так сделал. Переобьявил Tasks[] на **Tasks, с delete начала прога вылетать, убрал строки с delete, вроде заработало.

Макросами пока не пользовался, временно сделал вызов таким:
Код:
    Thread1 myThread1(allTasks, sizeof(allTasks)/sizeof(allTasks[0]));
    Thread2 myThread2(allTasks, sizeof(allTasks)/sizeof(allTasks[0]));

Вроде пока всё заработало.

Спасибо.

ЗЫ да C++ у меня хромает, сори, учусь.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 13, 2010, 16:47 »

Ок, так сделал. Переобьявил Tasks[] на **Tasks, с delete начала прога вылетать, убрал строки с delete, вроде заработало.
Просто убрать - ошибка, Вы должны удалять старый массив когда пришел новый, иначе получите утечку памяти. Проследите что Tasks инициализирован нулем в конструкторе.
Записан
labview
Гость
« Ответ #7 : Август 13, 2010, 16:50 »

А как это сделать? И ещё мы ведь и так находимся в конструкторе, чем он может быть ещё инициализирован если обьект только только начинает своё существование?

Спасибо.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #8 : Август 13, 2010, 16:58 »

Цитировать
Просто убрать - ошибка, Вы должны удалять старый массив когда пришел новый, иначе получите утечку памяти. Проследите что Tasks инициализирован нулем в конструкторе.

Да нафига в конструкторе то delete? Я понимаю, он (конструктор) без аргументов был, а запись массива производилась бы в какой-нить другой функции уже позже.. Тогда, да в конструкторе не грех и занулить Tasks = 0;
Но в данной ситуации delete в конструкторе - это ошибка.
Когда мы в конструкторе вызываем
Код
C++ (Qt)
delete [] Tasks;
 
что он будет пытаться удалить? Мусор))
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Август 13, 2010, 17:09 »

Да нафига в конструкторе то delete?
Пардон, фигню спорол  Улыбающийся  Совсем не увидел что это сам конструктор и есть - тогда конечно не надо
Записан
Nimbus
Гость
« Ответ #10 : Август 16, 2010, 04:13 »

Код
C++ (Qt)
   for(int i = 0; i < tasksCount; i++)
    Tasks[i] = allTasks[i];
 

memcpy(Tasks, allTasks, sizeof(Tasking*) * tasksCount);
Подмигивающий
Записан
SASA
Гость
« Ответ #11 : Август 18, 2010, 14:23 »

Люди! Пользуйтесь QList, QSet, и т.д. Использвать сишные массивы надо только в КРАЙНЕМ случае.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Август 18, 2010, 14:34 »

Люди! Пользуйтесь QList, QSet, и т.д. Использвать сишные массивы надо только в КРАЙНЕМ случае.
Хмм... если человек еще не владеет С массивами и сразу начнет с контейнеров - получится совсем не гуд  Улыбающийся
Записан
Sancho_s_rancho
Гость
« Ответ #13 : Август 18, 2010, 15:33 »

Люди! Пользуйтесь QList, QSet, и т.д. Использвать сишные массивы надо только в КРАЙНЕМ случае.
Хмм... если человек еще не владеет С массивами и сразу начнет с контейнеров - получится совсем не гуд  Улыбающийся
Согласен. Хотя недавно я тут читывал книгу для изучающих С++ от Страуструпа , так он сразу, с первых примеров, начинает показывать на векторах и с исключениями. Книга зовется "Principles and Practice Using C++" . Если учесть, что исключения в С++ - это еще тот геморрой (т.е. задумка хорошая, а вот реализация проблемная), а шаблонные классы внутрях часто содержат массивы, указатели и malloc/realloc/free, то такое засирание мозгов выглядит странным.
ПиСи "принципы и практика использования C++" - книга именно для начинающих, по ней Бьярн читает лекции молодым студентам.
« Последнее редактирование: Август 18, 2010, 15:36 от Sancho_s_rancho » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 1.369 секунд. Запросов: 23.