Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Shaman163
5 / 5 / 0
Регистрация: 22.12.2011
Сообщений: 134
#1

Новый поток внутри класса - C++

21.08.2013, 13:32. Просмотров 1126. Ответов 12
Метки нет (Все метки)

Всем привет, решил попытаться оседлать многопоточность. Но увы тут же наткнулся на полное отсутствие информации.
Серьёзно, на любом посещённом мною ресурсе описывается либо теоретическая часть (которая мне вроде бы и так понятна),
либо сильно замудрённая практическая (которая уже требует каких то минимальных знаний).
И ни где толком не объясняется как именно реализовывать многопоточность. В частности меня интересует вопрос, как запустить виртуальный метод класса в отдельном потоке?
В качестве среды разработки использую QT Creator 2.7 MinGW32 (разумеется без использования самой QT)
Вот пример(вполне рабочий) исполнения метода в отдельном потоке который я всё таки откопал где то:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
void Build( void* pParams)
{
 
}
int main()
{
    _beginthread(Build, 0, NULL );
    return 0;
}
Однако, стоит запихать всё это в класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class Base
{
public:
 
    void Build( void* pParams)
    {
 
    }
    Base()
    {
        _beginthread(Build, 0, NULL );
    }
};
Получаем ошибку...
<<cannot convert 'Base::Build' from type 'void (Base:: )(void*)' to type 'void (__attribute__((__cdecl__)) *)(void*)'>>

Помогите пожалуйста, и если не трудно скиньте хороший ресурс(не книгу) по теме, чтобы впредь подобных тем не писать..
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.08.2013, 13:32
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Новый поток внутри класса (C++):

Поток внутри класса, реальность или плод моей фантазии? - C++
Дело в том, что для потока нужна статическая функция (все денные в классе НЕ статические), но будут ли независимые друг от друга потоки...

Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде локальной переменной внутри функции. - C++
Совсем не понял эту тему. Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде...

Использование перегруженного оператора ввода/вывода в поток базового класса для объекта производного класса - C++
Здравствуйте! Можно ли использовать перегруженный оператор ввода/вывода в поток из базового класса для объекта производного класса, если...

Создать объект внутри класса, который может вызывать функцию этого класса - C++
Ребята помогите уже несколько дней мучаюсь. Хочу сделать программу в консоле демонстрации работы лифта в здании 2 этажа. Сделал класс...

BST дерево. Инициализация класса внутри класса - C++
Здравствуйте, нужно реализовать класс дерева бинарного поиска с использованием итератора. Возник вопрос, как инициализировать через...

delete внутри класса для самого класса - C++
Доброго времени суток, пишу программу для работы с матрицами. По условию дали лишь несколько библиотек, ни векторов ни cstdio. Для...

12
Jupiter
Каратель
Эксперт С++
6568 / 3989 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
21.08.2013, 13:43 #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
class Base
{
public:
    void DoSomething()
    {
 
    }
 
    Base()
    {
    }
};
 
void Build(void* pParams)
{
    Base* ptr = static_cast<Base*>(pParams);
    ptr->DoSomething();
}
 
int main()
{
    Base obj;
    _beginthread(Build, 0, &obj);
    return 0;
}
1
Croessmah
Ушел
13766 / 8016 / 924
Регистрация: 27.09.2012
Сообщений: 19,734
Записей в блоге: 3
Завершенные тесты: 1
21.08.2013, 13:49 #3
Цитата Сообщение от Shaman163 Посмотреть сообщение
Серьёзно, на любом посещённом мною ресурсе описывается либо теоретическая часть
http://www.ozon.ru/context/detail/id/17636939/
0
Shaman163
5 / 5 / 0
Регистрация: 22.12.2011
Сообщений: 134
21.08.2013, 13:59  [ТС] #4
Цитата Сообщение от Jupiter Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
class Base
{
public:
    void DoSomething()
    {
 
    }
 
    Base()
    {
    }
};
 
void Build(void* pParams)
{
    Base* ptr = static_cast<Base*>(pParams);
    ptr->DoSomething();
}
 
int main()
{
    Base obj;
    _beginthread(Build, 0, &obj);
    return 0;
}
Так в том то и соль, что мне нужна реализация именно внутри класса.
От Base будут наследоваться другие классы внутри которых будут расчёты больших объёмов данных они то в свою очередь и должны исполнятся в отдельных потоках.
По моей задумке должен быть общих метод Build содержимое которого я буду переписывать в зависимости от наследника, однако исполнение его будет в отдельном потоке.
0
Kuzia domovenok
2125 / 1955 / 194
Регистрация: 25.03.2012
Сообщений: 6,804
Записей в блоге: 1
21.08.2013, 14:19 #5
при чём тут вообще наследование?
0
Jupiter
Каратель
Эксперт С++
6568 / 3989 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
21.08.2013, 14:21 #6
Цитата Сообщение от Shaman163 Посмотреть сообщение
Так в том то и соль, что мне нужна реализация именно внутри класса.
вы никак не засунете метод класса в beginthread

Цитата Сообщение от Shaman163 Посмотреть сообщение
От Base будут наследоваться другие классы внутри которых будут расчёты больших объёмов данных они то в свою очередь и должны исполнятся в отдельных потоках.
По моей задумке должен быть общих метод Build содержимое которого я буду переписывать в зависимости от наследника, однако исполнение его будет в отдельном потоке.
отлично, в чем проблема?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
 
void Build(void* pParams); 
 
class Base
{
public:
    virtual ~Base() {}
    
    virtual void Build()
    {
        std::cout << "Base::Build" << std::endl;
    }
    
    void Run()
    {
        _beginthread(::Build, 0, this);
    }
};
 
class Derived : public Base
{
public:
    virtual ~Derived() {}
    
    virtual void Build()
    {
        std::cout << "Derived::Build" << std::endl;
    }
};
 
void Build(void* pParams)
{
    Base* ptr = static_cast<Base*>(pParams);
    ptr->Build();
}
 
int main()
{
    Derived obj;
    obj.Run();
    return 0;
}
1
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
21.08.2013, 19:04 #7
std::thread
0
Shaman163
5 / 5 / 0
Регистрация: 22.12.2011
Сообщений: 134
27.08.2013, 14:51  [ТС] #8
Окей, другой вопрос. Как в таком случае уберечь Base::Build от вызова из вне???
Он ведь публичный...
Да и метод потока хотелось бы уберечь от возможности вызова не из конструктора Base
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
27.08.2013, 14:53 #9
Не понял вопроса, конкретизируй - постараюсь помочь.
0
Shaman163
5 / 5 / 0
Регистрация: 22.12.2011
Сообщений: 134
27.08.2013, 15:23  [ТС] #10
Вот мой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void Thread(void* pParams);
 
class Base
{
public:
    virtual void Build()
    {
        cout << "Base" << endl;
    }
    Base()
    {
        _beginthread(::Thread,0,this);
    }
};
 
class Image : Base
{
public:
    virtual void Build()
    {
        cout << "Image" << endl;
    }
 
};
 
void Thread(void* pParams)
{
    Base* ptr = static_cast<Base*>(pParams);
    ptr->Build();
}
1) Проблема в том что Build() обязательно должен быть публичным, однако я хочу ограничить возможность его вызова. Иначе говоря он должен вызываться только в конструкторе Base и нигде более
2) С методом Thread() аналогично...
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
27.08.2013, 15:27 #11
В конструкторе Base его корректно вызывать не получится, так как будет вызываться только Base::Build, но не Build, переопределенный в наследниках.
Придется сделать какой-то метод типа Base::start, который и будет запускать Build в отдельном потоке.
0
Raali
639 / 343 / 42
Регистрация: 06.07.2013
Сообщений: 1,107
Завершенные тесты: 1
27.08.2013, 16:51 #12
Вот как то так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <process.h>
#include <iostream>
 
class Base;
typedef void (*func_type)(void*);
 
class Base
{
public:
 
    static void Build( void* pParams) {std::cout << "Base\n";};
 
    void Init(func_type f) 
    {
        _beginthread(f, 0,(void*)this);
    }
 
    Base(func_type f)
    {
        Init(f);
    }
 
    Base()  {Init(Base::Build);}
 
};
 
class Inherited : public Base
{
 
    static void Build(void* pParams){std::cout << "Inherited\n";}
 
    public:
    Inherited() : Base(Inherited::Build) {}
};
 
 
 
int main()
{
    Base b; // пишет "Base"
    Inherited i; // пишет "Inherited"
    system("pause");
}
1
Shaman163
5 / 5 / 0
Регистрация: 22.12.2011
Сообщений: 134
28.08.2013, 18:35  [ТС] #13
Цитата Сообщение от Герц Посмотреть сообщение
В конструкторе Base его корректно вызывать не получится, так как будет вызываться только Base::Build, но не Build, переопределенный в наследниках.
Придется сделать какой-то метод типа Base::start, который и будет запускать Build в отдельном потоке.
Либо вы не правы, либо я чего то не допонял, тот код что я предоставил, корректно работает..
В консоли я вижу как Base так и Image. В теории как я понимаю, в конструкторе вызывается последнее переопределение до текущего наследника, в моём случае это Image.
На всякий случай, вот последняя версия кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
 
using namespace std;
 
void Thread(void* pParams);
 
class Base
{
public:
    virtual void Build()
    {
        cout << "Base" << endl;
    }
    Base()
    {
        _beginthread(::Thread,0,this);
    }
};
 
class Image : Base
{
public:
    virtual void Build()
    {
        cout << "Image" << endl;
    }
 
};
 
void Thread(void* pParams)
{
    Base* ptr = static_cast<Base*>(pParams);
    ptr->Build();
}
 
int main()
{
    Base b1;
    Image b2;
    system("pause");
    return 0;
}
Цитата Сообщение от Raali Посмотреть сообщение
Вот как то так
Большое спасибо за пример, как только разберусь в коде отпишусь о результатах.
0
28.08.2013, 18:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2013, 18:35
Привет! Вот еще темы с ответами:

Заполнение вектора класса внутри самого класса - C++
class A { private: int a; public: A() { a = 0; }; A get(vector &lt;A&gt;* vec)

Методы класса внутри определения класса - C++
Все привет! Решил закрепить свои знания по C++, читаю Р.Лафоре - &quot;Объектро-ориентированное программирование в C++&quot;. В книге, на...

Видимость экземпляра класса внутри класса - C++
Здравствуйте! Пытаюсь вывести openCV видео в QT виджете. На данный момент в слоте обновления картинки инициализирую класс cv::VideoCapture...

Объявление дружественного класса внутри класса - C++
class A{ friend class B{ B(A &amp;a); } } Подскажите пожалуйста, такое возможно или нет, я хотел чтобы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru