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

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.78
GoldenId
126 / 124 / 32
Регистрация: 11.11.2010
Сообщений: 683
Записей в блоге: 13
Завершенные тесты: 1
#1

callback метода класса - C++

17.11.2010, 15:21. Просмотров 2460. Ответов 2
Метки нет (Все метки)

Предыстория: нужно последовательно запускать несколько однотипных циклов большой степени вложенности, в теле которых вызывать разные функции.
Т.к. вроде бы переписывать циклы (тем более громоздкие по STL-ным контейнерам) плохо, то я решил сделать одну функцию, в которой реализуется цикл, в теле которого вызывается переданная в качестве параметра callback-функция. Все эти функции имели отношение к классу, так что и callback функция-
являлась методом.
Далее по существу.

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
// класс "учебный процесс" - оформляет последовательность
// действий в программе
class CStudy {
    // деканат, который содержит и всю остальную структуру
    CDeanery deanery;
 
public:
    // обработка всего учебного процесса в течение семестра
    void CStudy::Process() {
        
        Init();                 // инициализация всей системы
        SelectQualWorks();      // выбор квалификационных работ студентами
        ExecuteOrders();        // выполнение приказов
        MakeExams();            // проведение экзаменов
        MakeCritics();          // написание рецензий
        ProtectQualWorks();     // защита квалификационных работ
        CreateFateOrders();     // создание приказов по результату сессии
        ExecuteOrders();        // выполнение приказов
    }
private:
    // инициализация всей системы
    void Init() {
        deanery.Init();
    }
    // выбор квалификационных работ для всех выпукников - и выпуск приказов
    void SelectQualWorks() {
        ForEachStudent( &CStudy::SelectQualWork );  // (1)
    }
    // провести экзамены для всех студентов - получить их нижние оценки
    void MakeExams() {
        ForEachStudent( &MakeExam );    // (2)
    }
    // написание рецензий для кв. работ всех студентов, кто пишет кв. работы
    void MakeCritics() {
        ForEachStudent( &MakeCritic );  // (3)
    }
    // защита кв. работ всех студентов, пишущих кв. работы
    void ProtectQualWorks() {
        ForEachStudent( &ProtectQualWork ); // (4)
    }
    // создание приказов по результату сессии
    void CreateFateOrders() {
        deanery.CreateFateOrders();
    }
    // выполнение текущих приказов
    void ExecuteOrders() {
        deanery.ExecuteOrders();
    }
 
 
private:
    //// функция-параметр для исполнения для каждого студента
    //typedef void CStudy::ProcessStudent( CStudent* );
    //typedef ProcessStudent* PProcessStudent;
 
    // функциия, исполняющая выполняющая свою функцию-параметр надо всеми студентами
    void ForEachStudent( void ( *CStudy::pFunc )( CStudent * ) );
 
    // выбрать работу одним студентом
    void SelectQualWork( CStudent *st );
    // пройти экзамен одним студентом
    void MakeExam( CStudent *st );
    // написать рецензию для кв. работы студента
    void MakeCritic( CStudent *st );
    // провести защиту кв. работы студента
    void ProtectQualWork( CStudent *st );
 
 
 
};
Собственно такой кульбит с CStudy:: в (1) обусловлен попыткой исправить ошибку аналогичную возникающим в строках (2), (3), (4). Итак ошибки следующие:
(2), (3), (4) :
C++
1
Error   2   error C2276: '&' : illegal operation on bound member function expression    d:\!study\тти\3 семестр\ооп\oop\oop_course\study.h  36
(1) :
C++
1
Error   1   error C2664: 'CStudy::ForEachStudent' : cannot convert parameter 1 from 'void (__thiscall CStudy::* )(CStudent *)' to 'void (__cdecl *)(CStudent *)'    d:\!study\тти\3 семестр\ооп\oop\oop_course\study.h  32
Мне кажется (1) шаг в сторону исправления, но помогите добить эту маленькую... Заранее признателен за конструктив.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.11.2010, 15:21
Здравствуйте! Я подобрал для вас темы с ответами на вопрос callback метода класса (C++):

Указатель на метод класса в качестве аргумента метода класса - C++
Функция _createFun вызывается для создания ХХХ в основном классе. Но вот потребовалось создать ХХХ в дополнительном классе. Вопрос: как...

Запуск метода класса в новом потоке - C++
Здравствуйте, у меня есть класс, в нём функция - необходимо вызвать эту функцию в нескольких потоках, возможно ли это?

Явная специализация метода для типа шаблонного класса - C++
Добрый вечер, уважаемые знатоки! :) Хочу задать вопрос по созданию шаблонов. В общем, пусть у меня есть шаблон некоторого класса: ...

CALLBACK - C++
Здравствуйте, уважаемые форумчане. Передо мной стоит задача записи звука с микрофона в файл. Как считывать в буфер я разобрался. Но не...

callback функция - C++
Здраствуйте!!! Занимаюсь разработкой снифера под DVB-карту. Пытаюсь получить MPEG-поток. Проблема заключается в том, что необходимо...

Метод класса не работает как callback-функция - C++ Builder
Всем привет! Помогите разобраться с синтаксисом. Есть gui-прога, в которой содержится функция TForm4::kau2_2_callback(float value) ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Nick Alte
Эксперт С++
1636 / 1008 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
17.11.2010, 19:44 #2
Как правильно использовать указатели на методы класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
public:
    void foo() {}
    void bar() {}
};
 
int main()
{
    void (A::*f) () = &A::foo;  // Указатель на функцию из A. Обратим внимание на способ получения адреса метода.
    A *a = new A(); 
    (a->*f)();   // Вызов метода по указателю на существующий объект типа A
    f = &A::bar;
    (a->*f)();   // Вызов другого метода
    delete a;
}
Суть в том, что для вызова методов надо указывать и объект, на котором эти методы вызываются. В описанном случае можно пользоваться this. Ну и правильно извлекать адрес функции-члена.
GoldenId
126 / 124 / 32
Регистрация: 11.11.2010
Сообщений: 683
Записей в блоге: 13
Завершенные тесты: 1
18.11.2010, 11:52  [ТС] #3
Благодарю, Nick Alte. Но я читал статью по ошибкам в (2), (3), (4). Поэтому и попробовал сделать (1), но не получилось. По сравнению с вашим ответом, я хочу, чтобы мне разжевали, как я должен написать функцию ForEachStudent и как её вызывать, потому что у меня соображения закончились.

Добавлено через 12 минут
О! Спасибо, кажется, разобрался. Значит при вызове главное, что адрес функции-члена указывается относительно адреса объекта (если она не статическая) и это отражает синтаксис
C++
1
2
    A *a = new A(); 
    (a->*f)();   // Вызов метода по указателю на существующий объект типа A
Также и при объявлении.
C++
1
   void (A::*f) ();
Благодарю
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2010, 11:52
Привет! Вот еще темы с ответами:

Ошибка при реализации метода класса - C++ Builder
Всем здрасьте. Возникла проблема при реализации метода класса. Никак не могу понять, в чём дело. Помогите, пжалста :/ Объявление...

Вызов статического метода абстрактного класса - C++ Builder
возможно ли вызвать статический метод из абстрактного класса? это делается только с помощью переопределения метода, верно? Добавлено...

Передача метода класса в качестве параметра для метода другого класса - C++
Здравствуйте, Передо мной стоит такая задача. Необходимо разработать механизм, который бы мог прервать любую функцию, при этом абсолютна...

Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода - C#
В базовом классе метод помечен как virtual. Насколько я понял из книги: override означает, что метод не утрачивает связи с базовым...


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

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

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