Форум программистов, компьютерный форум CyberForum.ru

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

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

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

21.08.2013, 13:32. Просмотров 844. Ответов 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*)'>>

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

C++ Поток внутри класса, реальность или плод моей фантазии?
Инициализация класса A внутри класса B C++
C++ Нужно закрыть поток thread и открыть новый для sleep
Объявление дружественного класса внутри класса C++
C++ Использование перегруженного оператора ввода/вывода в поток базового класса для объекта производного класса
Нужно создать базу данных (создать пустой бинарный файл). Через поток. Поток бинарного файла описать в виде локальной переменной внутри функции. C++
C++ delete внутри класса для самого класса
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт C++
6548 / 3968 / 226
Регистрация: 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;
}
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12516 / 7078 / 796
Регистрация: 27.09.2012
Сообщений: 17,483
Записей в блоге: 2
Завершенные тесты: 1
21.08.2013, 13:49     Новый поток внутри класса #3
Цитата Сообщение от Shaman163 Посмотреть сообщение
Серьёзно, на любом посещённом мною ресурсе описывается либо теоретическая часть
http://www.ozon.ru/context/detail/id/17636939/
Shaman163
4 / 4 / 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 содержимое которого я буду переписывать в зависимости от наследника, однако исполнение его будет в отдельном потоке.
Kuzia domovenok
 Аватар для Kuzia domovenok
1886 / 1741 / 117
Регистрация: 25.03.2012
Сообщений: 5,916
Записей в блоге: 1
21.08.2013, 14:19     Новый поток внутри класса #5
при чём тут вообще наследование?
Jupiter
Каратель
Эксперт C++
6548 / 3968 / 226
Регистрация: 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;
}
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
21.08.2013, 19:04     Новый поток внутри класса #7
std::thread
Shaman163
4 / 4 / 0
Регистрация: 22.12.2011
Сообщений: 134
27.08.2013, 14:51  [ТС]     Новый поток внутри класса #8
Окей, другой вопрос. Как в таком случае уберечь Base::Build от вызова из вне???
Он ведь публичный...
Да и метод потока хотелось бы уберечь от возможности вызова не из конструктора Base
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
27.08.2013, 14:53     Новый поток внутри класса #9
Не понял вопроса, конкретизируй - постараюсь помочь.
Shaman163
4 / 4 / 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() аналогично...
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
27.08.2013, 15:27     Новый поток внутри класса #11
В конструкторе Base его корректно вызывать не получится, так как будет вызываться только Base::Build, но не Build, переопределенный в наследниках.
Придется сделать какой-то метод типа Base::start, который и будет запускать Build в отдельном потоке.
Raali
622 / 326 / 34
Регистрация: 06.07.2013
Сообщений: 1,049
Завершенные тесты: 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");
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2013, 18:35     Новый поток внутри класса
Еще ссылки по теме:

BST дерево. Инициализация класса внутри класса C++
C++ Создать объект внутри класса, который может вызывать функцию этого класса
C++ Методы класса внутри определения класса
C++ Видимость экземпляра класса внутри класса
C++ Заполнение вектора класса внутри самого класса

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

Или воспользуйтесь поиском по форуму:
Shaman163
4 / 4 / 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 Посмотреть сообщение
Вот как то так
Большое спасибо за пример, как только разберусь в коде отпишусь о результатах.
Yandex
Объявления
28.08.2013, 18:35     Новый поток внутри класса
Ответ Создать тему
Опции темы

Текущее время: 19:29. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru