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

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

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

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

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

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

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

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

Передача указателя функции класса A в класс B
Добрый день! Стоит задача вызывать функцию другого класса в потоке, ну что то типа этого: typedef void (t1::*PTR_FUN)(int);...

5
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
01.08.2017, 13:34
Цитата Сообщение от tnk500 Посмотреть сообщение
Как можно создать свой класс, чтобы он мог принимать функции и любые параметры к ним, как и std::thread, тем не менее чтобы он догадывался, что если ему подали указатель на метод и указатель на объект, он вызвал от имени этого объекта этот метод?
Комбинацией шаблонов и перегрузок, например.
1
 Аватар для Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 285
Записей в блоге: 1
01.08.2017, 13:47
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  [ТС]
Отлично, понял как оно работает.

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
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
01.08.2017, 15:10
Цитата Сообщение от 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  [ТС]
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.08.2017, 15:23
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru