Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
1

Передача функции указателя на метод класса и его объекта для вызова

01.08.2017, 13:34. Просмотров 2411. Ответов 5
Метки нет (Все метки)

std::thread позволяет в качестве исполняемой функций принимать метод класса и указатель на его объект, чтобы потом вызвать от имени этого объекта данный метод:

C++
1
std::thread t(&Class::Method, &obj);
Впоследствии obj->Method() будет вызван в отдельном потоке.

Как можно создать свою функцию, чтобы она могла принимать функции и любые параметры к ним, как и конструктор std::thread, тем не менее чтобы она догадывалась, что если ей подали указатель на метод и указатель на объект, она вызвала от имени этого объекта этот метод? Просто в определении класса std::thread стоит обычный шаблон с произвольным набором параметров и мне не ясно, как отдельно обрабатывается такой случай.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.08.2017, 13:34
Ответы с готовыми решениями:

Передача всего объекта в метод Main для вызова метода
Добрый день! Подскажите пожалуйста. Есть например класс Student. В нём есть свойства...

Получение указателя на метод объекта по его имени
Доброго времени суток. Как получить метод объекта имея в строковой переменной его имя, по аналогии...

Передача указателя функции класса A в класс B
Добрый день! Стоит задача вызывать функцию другого класса в потоке, ну что то типа этого: ...

Передача объекта класса в метод другого класса
Доброго времени суток! Есть следующие классы: public class TestClass : IDisposable { ...

5
844 / 775 / 258
Регистрация: 27.07.2012
Сообщений: 2,180
01.08.2017, 13:34 2
Цитата Сообщение от tnk500 Посмотреть сообщение
Как можно создать свой класс, чтобы он мог принимать функции и любые параметры к ним, как и std::thread, тем не менее чтобы он догадывался, что если ему подали указатель на метод и указатель на объект, он вызвал от имени этого объекта этот метод?
Комбинацией шаблонов и перегрузок, например.
1
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
01.08.2017, 13:47 3
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
#include <iostream>
#include <string>
#include <functional>
#include <thread>
 
class A
{
public:
        void memFunc( int _a )
        {
            std::cout << _a << std::endl;
        }
};
 
void threadFunc( std::function< void( int ) > _memFun )
{
    _memFun( 321 );
}
 
int main()
{
    A obj;
    
    std::function< void( int ) > memFunc = std::bind( &A::memFunc, obj, std::placeholders::_1 );
    std::thread thr( threadFunc, memFunc );
    
    thr.join();
    return 0;    
}
0
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
01.08.2017, 14:29  [ТС] 4
Отлично, понял как оно работает.

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>
#include <thread>
 
class Class
{
public:
    void Hello(int a, float b)
    {
        std::cout << "Hello there, " << a << " and " << b << "!\n";
    }
};
 
// Для обычных функций
template<class Callable, class...Args>
void RunFunction(Callable&& func, Args&&...args)
{
    func(std::forward<Args>(args)...);
}
 
// Для методов классов
template<class _Class, class...Args>
void RunFunction(void(_Class::*member_func_ptr)(Args...), _Class* obj, Args&&...args)
{
    (obj->*member_func_ptr)(std::forward<Args>(args)...);
}
 
int main()
{
    Class obj;
 
    RunFunction(&Class::Hello, &obj, 1, 2.5f);
 
    std::thread t(&Class::Hello, &obj, 10, 25.5f);
 
    t.join();
 
    std::cin.get();
}
 
 
// Вывод: 
//  Hello there, 1 and 2.5!
//  Hello there, 10 and 25.5!
Но вот что странно: у std::thread есть лишь один конструктор, который описан как RunFunction для обычных функций. Второго нет. Потом по цепочке вызовов эти все параметры передаются реализации C++ Runtime. Интересно, сделано ли там именно таким образом всё. Тогда интересно, что параметры можно вот так передавать по цепочкам, и лишь уже в последнем звене решать, подали ли тебе обычную функцию или указатель на метод с указателем на объект и аргументами
0
491 / 206 / 69
Регистрация: 27.05.2016
Сообщений: 551
01.08.2017, 15:10 5
Цитата Сообщение от tnk500 Посмотреть сообщение
есть лишь один конструктор, который описан как RunFunction для обычных функций. Второго нет.
Скорее всего там все спрятано в внутренней реализации наподобие :
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
namespace detail
{
 
    template<class R, class _Class, class...Args>
    void RunFunction_impl(R(_Class::*member_func_ptr), _Class& obj, Args &&...args) {
        (obj.*member_func_ptr)(std::forward<Args>(args)...);
    }
 
    template<class R, class _Class, class...Args>
    void RunFunction_impl(R(_Class::*member_func_ptr), const _Class& obj, Args &&...args) {
        (obj.*member_func_ptr)(std::forward<Args>(args)...);
    }
 
    template<class Callable, class...Args>
    void RunFunction_impl(Callable&& func, Args&&...args)
    {
        func(std::forward<Args>(args)...);
    }
 
}//end namespase detail
 
template<class Callable, class...Args>
void RunFunction(Callable&& func, Args&&...args)
{
    detail::RunFunction_impl(std::forward<Callable>(func), std::forward<Args>(args)...);
}
1
117 / 121 / 42
Регистрация: 25.08.2012
Сообщений: 1,294
01.08.2017, 15:23  [ТС] 6
notAll, не думал, что такое вообще возможно, хотя если подумать, не фантастично.

C++
1
2
3
4
5
template<class Callable, class...Args>
void ProxyRunFunction(Callable&& func, Args&&...args)
{
    RunFunction(std::forward<Callable>(func), std::forward<Args>(args)...);
}
Если вызывать её вместо этих, всё передаётся корректно и версии RunFunction запускаются корректные. Пожалуй, это для меня было неожидано, но однознаначно круто.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.08.2017, 15:23

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Передача объекта в метод класса
здравствуйте. в процессе написания программы возник такой вопрос. можно ли при вызове метода...

Передача неизвестного объекта в метод класса
Ситуация такова: имеется класс (в зачаточном состоянии) class Archer { private: double...

Передача переменной в метод open() объекта класса fstream
При попытке передать переменную в метод объекта класса fstream выдаёт ошибку &quot;error: no matching...

Сериализация объекта класса и передача его по TCP
Отредактировал найденный пример из сети, но при работе клиента выбивает ошибку: Необработанное...


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

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

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