С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/34: Рейтинг темы: голосов - 34, средняя оценка - 4.50
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367

Указатель на привязанную функцию можно использовать только для вызова функции

25.11.2024, 16:46. Показов 13588. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Parent является родительским классом.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Logger;
 
class Parent {
public:
    Logger* logger;
    bool work = false;
    thread* functhread;
    string name = "Worker";
    void Main();
    Parent(Logger* l);
    void Exit();
};
 
Parent::Parent(Logger* l) {
    this->logger = l;
    this->work = true;
    this->logger->SendSignal(this, STARTED, "[" + name + "] Starting...");
    this->functhread = new thread(this->Main); // Здесь ошибка
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.11.2024, 16:46
Ответы с готовыми решениями:

Указатель на привязанную функцию можно использовать только для вызова функции
int ident=mflats.at(1).GetIdent; Объясните пожалуйста, почему нельзя использовать такую форму? (функции Int, возвращает нужное мне...

Указатель для вызова виртуальной функции
Помогите разобраться в строении вызова виртуальной функции Если не сложно, объсните каждый указатель #include <iostream> ...

Использовать функции, сохраняя в main () только обращения к функции. Обеспечить передачу параметров в функцию
Помогите пожалуйста с программкой! При решении задачи обязательно использовать функции, сохраняя в main () только обращения к функции....

20
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
25.11.2024, 16:48
Естественно
C++
1
this->functhread = new thread(&Parent::Main,this);
и главное, нафига указатель на thread??
1
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
25.11.2024, 17:44  [ТС]
Цитата Сообщение от Azathtot Посмотреть сообщение
нафига указатель на thread??
Для его управления в будущем

Добавлено через 52 минуты
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include <SFML/Graphics.hpp>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <vector>
#include <string.h>
 
#pragma comment(lib, "sfml-audio.lib")
#pragma comment(lib, "sfml-graphics.lib")
#pragma comment(lib, "sfml-network.lib")
#pragma comment(lib, "sfml-system.lib")
#pragma comment(lib, "sfml-window.lib")
 
using namespace std;
 
enum LoggerMessageLevel {
    DEBUG = -1,
    INFO,
    WARN,
    ERROR,
    FATAL,
    STARTED,
    STOPPED
};
 
class Logger;
 
class Parent {
public:
    Logger* logger;
    bool work = false;
    thread* functhread;
    string name = "Worker";
    void Main() {}
    Parent(Logger* l);
    void Exit();
};
 
class Logger {
public:
    ostream* strm;
    vector<string> pool;
    vector<Parent*> threads;
    using threadsIter = vector<Parent*>::iterator;
    using poolIter = vector<string>::iterator;
    bool work;
    Logger(ostream*);
    void LoggerWorker();
    threadsIter FindThread(Parent*);
    void SendSignal(Parent*, LoggerMessageLevel, string);
};
 
Parent::Parent(Logger* l) {
    this->logger = l;
    this->work = true;
    this->logger->SendSignal(this, STARTED, "[" + name + "] Starting...");
    this->functhread = new thread(&Parent::Main, this);
}
void Parent::Exit() {
    this->work = false;
    this->logger->SendSignal(this, STOPPED, "[" + name + "] Stopped!");
}
 
Logger::Logger(ostream * stream) {
    this->strm = stream;
    this->work = true;
}
void Logger::LoggerWorker()
{
    if (!this->work) { if (this->strm->good()) { this->strm->operator<<("[DEBUG] Logger isn't inited!"); } }
    while (this->work) {
        for (poolIter iter = this->pool.end(); iter != this->pool.begin(); iter--) {
            this->strm->operator<<((*iter).c_str());
        }
        this_thread::sleep_for(chrono::milliseconds(10));
    }
    this->strm->operator<<("[DEBUG] Logger is stopped!");
}
Logger::threadsIter Logger::FindThread(Parent* elem) {
    for (Logger::threadsIter iter = this->threads.begin(); iter != this->threads.end(); iter++) { if (*iter == elem) { return iter; } }
}
void Logger::SendSignal(Parent* elem, LoggerMessageLevel level, string message) {
    string formatted;
    if (level == STARTED) {
        this->threads.push_back(elem);
    }
    if (level == STOPPED) {
        this->threads.erase(FindThread(elem), FindThread(elem));
    }
    if (level == FATAL) {
        for (auto& thrd : this->threads) {
            thrd->Exit();
        }
        this->work = false;
    }
}
 
class Window : public Parent {
    Window(Logger* l) : Parent(l) {}
    void Main();
};
 
class Window : public Parent {
    string name = "Window-Worker";
    Window(Logger* l) : Parent(l) {}
    void Main() {
        {
            sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
 
            while (window.isOpen())
            {
                sf::Event event;
                while (window.pollEvent(event))
                {
                    if (event.type == sf::Event::Closed)
                        window.close();
                }
 
                window.clear();
                window.display();
            }
        }
    }
};
 
int main()
{
    Logger* logger = new Logger(&cout);
    Window* window = new Window(logger);
 
    thread* lthread = new thread(&Logger::LoggerWorker, logger);
}
Ничего не происходит, сразу завершается с кодом 0
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
25.11.2024, 19:19
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
void Main() {}
Во-первых, надо немножко виртуальности добавить, иначе счегоб ему работать?
Добавьте virtual и не забудьте виртуальный деструктор.


Цитата Сообщение от ARRAYBOW Посмотреть сообщение
this->functhread = new thread(&Parent::Main, this);
Тут немножечко датарейса происходит.
Если повезёт, и main в новом потоке будет выполнен до окончания инициализации, будет UB (скорее всего вызван Parent::Main).

Пример, который скорее всего сработает, потому что пока там еще тред сработает... конструктор уже два раза завершится:
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
#include <string>
#include <thread>
#include <iostream>
#include <chrono>
 
class Parent {
public:
    Parent() : functhread{new std::thread(&Parent::Main, this)} {}
    virtual void Main() {
        std::cout << "DEFAULT" << std::endl;
    }
    virtual ~Parent() {
    }
private:
    std::thread *functhread;
};
 
class Window : public Parent {
public:
    Window() : Parent() {}
    void Main() override {
        std::cout << "I'm done!" << std::endl;
    }
};
 
int main() {
    Window window;
 
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
Пример, который точно не сработает, потому что конструктор не успеет завершиться до вызова треда:
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
#include <string>
#include <thread>
#include <iostream>
#include <chrono>
 
class Parent {
public:
    Parent() : functhread{new std::thread(&Parent::Main, this)} {
        functhread->join(); // подождём
    }
    virtual void Main() {
        std::cout << "DEFAULT" << std::endl;
    }
    virtual ~Parent() {
    }
private:
    std::thread *functhread;
};
 
class Window : public Parent {
public:
    Window() : Parent() {}
    void Main() override {
        std::cout << "I'm done!" << std::endl;
    }
};
 
int main() {
    Window window;
 
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
Посему, во избежание редких и трудноуловимых глюков, желательно в конструкторе подобных тредов не запускать.
0
 Аватар для Azathtot
754 / 351 / 90
Регистрация: 07.01.2023
Сообщений: 1,451
25.11.2024, 22:08
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
Для его управления в будущем
а что мешает управлять обычным std::thread?
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
26.11.2024, 17:05  [ТС]
Цитата Сообщение от Azathtot Посмотреть сообщение
а что мешает управлять обычным std::thread?
У меня он и есть
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
27.11.2024, 17:30  [ТС]
https://github.com/EgorBeLike/ConOs
Ошибка Failed to create texture, its internal size is too high (4294966592x4294966744, maximum is 16384x16384)
В OS.h в 31 строчке.
Также выдает исключение Вызвано исключение по адресу 0x00007FFD8108EA9B (sfml-graphics-2.dll) в ConOs.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFFFFFFFFFF. в Window.h в 63 строчке, возможно из-за ошибки выше
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
29.11.2024, 16:24  [ТС]
Цитата Сообщение от Azathtot Посмотреть сообщение
а что мешает управлять обычным std::thread?
Без указателей он не работает, оператор = не работает

Добавлено через 35 минут
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
Вызвано исключение по адресу 0x00007FFD8108EA9B (sfml-graphics-2.dll) в ConOs.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFFFFFFFFFFFFFFFF.
Подредактировал код, теперь d той же строчки ошибка Необработанное исключение по адресу 0x00007FFA4322286E (ucrtbase.dll) в ConOs.exe: Запрашивается выход из программы в результате неустранимой ошибки. из _purecall()
0
фрилансер
 Аватар для Алексей1153
6444 / 5639 / 1128
Регистрация: 11.10.2019
Сообщений: 15,007
29.11.2024, 18:10
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
оператор = не работает
его можно перемещать
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
30.11.2024, 17:12  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
его можно перемещать
У неинициализированной переменой-класса функции разве работают?
0
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
30.11.2024, 18:27
ARRAYBOW, та блин, он говорит о том, что можно (нужно, на самом деле) так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Logger;
 
class Parent {
public:
    Logger* logger;
    bool work = false;
    thread functhread;
    string name = "Worker";
    void Main();
    Parent(Logger* l);
    void Exit();
};
 
Parent::Parent(Logger* l) 
    : logger(l), work(true), functhread(&Parent::Main, this)  
{
    this->logger->SendSignal(this, STARTED, "[" + name + "] Starting...");
}
Добавлено через 25 минут
ARRAYBOW, Чо ты вообще делать-то хочешь?
Выглядит так, будто тут треды нафиг не нужны. Одевание штанов через голову.

У тебя SFML есть, асинхронная система. Зачем треды?

Ну даже если ладно. Допустим тред - это логгер, пусть будет (вопрос, что он будет конкурировать за std::cout тут даже не рассматриваем, хотя и нужно), а main loop SFML зачем в тред совать? Притом, что главный поток просто нифига не делает.

Цитата Сообщение от ARRAYBOW Посмотреть сообщение
Ничего не происходит, сразу завершается с кодом 0
Завершается твоя прога потому, что главный поток завершается. Его никто не держит. А если его держать тредом (напр через join), то тут жэ встает вопрос - нафига еще один тред, чтобы держать главный тред? - делай все в главном. (ну и возвращаемся в начало моего поста).

Добавлено через 1 минуту
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
Необработанное исключение по адресу
Всякие такие ошибки скорее всего из-за неаккуратной работы с ресурсами из многопотока, или неаккуратной работы с памятью. Чо ты там наворотил - не ясно. Но ясно, что код под выброс и переделать нормально. С пониманием того зачем и чо ты вообще делаешь.
1
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
30.11.2024, 18:51  [ТС]
Цитата Сообщение от ablex Посмотреть сообщение
Всякие такие ошибки скорее всего из-за неаккуратной работы с ресурсами из многопотока, или неаккуратной работы с памятью. Чо ты там наворотил - не ясно. Но ясно, что код под выброс и переделать нормально. С пониманием того зачем и чо ты вообще делаешь.
В https://github.com/EgorBeLike/... s/Window.h в 69 строчке, там цикл, где все объекты отрисовываются, оттуда исключение
0
фрилансер
 Аватар для Алексей1153
6444 / 5639 / 1128
Регистрация: 11.10.2019
Сообщений: 15,007
30.11.2024, 19:00
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
переменой-класса
я даже не знаю, что это такое
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
01.12.2024, 11:52  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sf::RenderWindow* window;
    map<Parent*, sf::Drawable*> pool;
    using poolIter = map<Parent*, sf::Drawable*>::iterator;
void Main() override {
        window = new sf::RenderWindow{ sf::VideoMode(x, y), NAME, sf::Style::Close | sf::Style::Titlebar };
        
        while (window->isOpen() && work)
        {
            window->clear();
            for (auto& sp : pool) {
                window->draw(*sp.second);
            }
            window->display();
        }
Должно работать но не работает, исключение в 10 строчке
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
02.12.2024, 15:39  [ТС]
C++
1
2
3
4
5
6
7
void Logger::RemoveThread(Parent* elem) {
    for (auto iter = this->threads.begin(); iter != this->threads.end(); iter++) {
        if (*iter == elem) {
            this->threads.erase(iter); 
        } 
    }
}
В 4 строке выходит исключение, на миниатюре показан стек вызовов потока, не понимаю почему, возможно из-за того что параллельно с этим потоком другие потоки тоже удаляют элементы. Только как решить проблему я не знаю. Буду пытаться пихать костыли
0
02.12.2024, 15:41  [ТС]

Не по теме:

Вот оно, забыл добавить

Миниатюры
Указатель на привязанную функцию можно использовать только для вызова функции  
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
02.12.2024, 15:41  [ТС]
...
Миниатюры
Указатель на привязанную функцию можно использовать только для вызова функции  
0
Чугунные скороходы
 Аватар для ARRAYBOW
17 / 16 / 3
Регистрация: 25.12.2022
Сообщений: 367
02.12.2024, 17:06  [ТС]
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
Буду пытаться пихать костыли
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Logger::RemoveThread(Parent* elem) {
    size_t i = 0;
    size_t threads_c = this->threads.size();
    bool done = false;
    while (!done) {
        i = 0;
        threads_c = this->threads.size();
        for (auto iter = this->threads.begin(); iter != this->threads.end(); iter++) {
            cout << to_string(i) << ";" << to_string(threads_c) << ";" << to_string(this->threads.size()) << "\n";
            if (threads_c != this->threads.size()) { break; }
            assert(i < this->threads.size());
            if (*iter == elem) {
                this->threads.erase(iter);
                done = true;
            }
            i++;
        }
    }
}
Вот, но когда остается 1 поток он не удаляет его, уходит в вечный цикл, где i всегда равно 0
0
фрилансер
 Аватар для Алексей1153
6444 / 5639 / 1128
Регистрация: 11.10.2019
Сообщений: 15,007
02.12.2024, 21:10
ARRAYBOW, а останавливать потоки будет Александр Сергеевич?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
03.12.2024, 11:27
Цитата Сообщение от ARRAYBOW Посмотреть сообщение
if (*iter == elem) {
                this->threads.erase(iter);
Это неправильное удаление из вектора. Подробнее: Распространенные ошибки
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.12.2024, 11:27
Помогаю со студенческими работами здесь

Можно ли передать указатель на функцию как параметр другой функции?
В общем, вопрос. Можно ли, допустим ... int fun1(int x) { ... ... ... return x*1000; }

Можно ли утверждать, что в C++ имя функции - константный указатель на функцию ?
В учебнике &quot;Освой самостоятельно C++ за 24 часа&quot; (Либерти, Хорват) говорится, что таки да. А ещё попадались мнения на форумах, что таки...

можно ли в Matlab создать библиотеку для С++ и использовать ее без вызова Matlab?
Возможно ли с помощью команды deploytool или какой-то другой команды создать библиотеку .dll например функции polyxpoly, чтобы в...

Вычислить значение функции y раскладывая функцию f(x) в ряд Тейлора. Для вычисления f(x) и факториала использовать рекурсивную функцию
Вычислить значение функции y раскладывая функцию f(x) в ряд Тейлора. Для вычисления f(x) и факториала использовать рекурсивную функцию. ...

Можно ли использовать register_post_type только для кастомного типа
Можно ли использовать register_post_type только для создания кастомного типа, но без использования его дополнительных параметров? То есть...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
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
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru