Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
 Аватар для ps10n1ck
56 / 50 / 11
Регистрация: 10.11.2010
Сообщений: 132

Указатель на функцию-член

13.11.2012, 03:20. Показов 2918. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток, возникла следующая ситуация:
Приведу пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A {
public:
    void a() { cout << "hello!"; };
};
 
class B {
public:
    void b(void (*pfunc)()) { pfunc(); };
};
 
 
int main(){
    A* a = new A;
    B* b = new B;
 
    b->b(a->a()); // ????????????
    
return 0;
}
при такой передаче параметра в функцию естественно произойдет ошибка:
C++
1
error C2664: 'B::b' : cannot convert parameter 1 from 'void' to 'void (__cdecl *)(void)'
Кто подскажет, как правильно и лучше передать указатель на функцию-член класса?
Функции не статические.

Добавлено через 8 минут
на данный момент у меня только такие решения есть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
A* a = new A;
B* b = new B;
 
void func(){
    a->a();
}
 
int main(){
    b->b(func); // ????????????
    
return 0;
}
или объявление функции a() как статическая
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.11.2012, 03:20
Ответы с готовыми решениями:

Указатель на функцию член
Вот урезаный донельзя код: class Window { public: ... bool registerClassEx()

Указатель на функцию-член
// howmany.cpp: определяет точку входа для консольного приложения. // #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include...

Указатель на функцию-член
Имеем следующий код: #include &lt;iostream&gt; using namespace std; class Windows { public: void OpenWindows() { cout &lt;&lt;...

16
2022 / 1621 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
13.11.2012, 03:59
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
#include <iostream>
 
class A {
    
public:
    void func() { 
    
        std::cout << "hello!" << std::endl;
    }
};
 
class B {
    
public:
    void func(void (A::*pfunc)(), A& obj) {  
    
        (obj.*pfunc)();
    }
};
 
 
int main() {
    
    A* a_obj = new A;
    B* b_obj = new B;
 
    b_obj->func(&A::func, *a_obj);
    
    delete a_obj;
    delete b_obj;
}
2
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 04:20
Почему не передавать указатель на сам класс ?

C++
1
void B::b(A* a) {  a->a()  };
1
 Аватар для ps10n1ck
56 / 50 / 11
Регистрация: 10.11.2010
Сообщений: 132
13.11.2012, 04:52  [ТС]
Проще говоря, есть класс B в котором реализован метод принимающий параметр как указатель на функцию. Какая функция и с какого класса эта функция будет - неизвестно. Проще говоря есть такие данные:
C++
1
2
3
4
5
6
class B {
public:
    void b(void (*pfunc)()){ 
        pfunc();
    };
};
и есть какой-то класс (как называется неизвестно), в котором есть метод X или Y, или Z - в общем заранее не известно как этот метод будет называться. Все, что мне нужно сделать, это в метод b() класса B передать некий метод с другого класса.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
13.11.2012, 04:54
Так передавай указатель на сам класс!
Не бойся сделать лишнюю обёртку в виде абстрактного класса с единственным методом.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 05:04
Поясню указатель на метод и указатель на ф-цию - разные вещи...
Указатель на метод - это смещение члена относительно класса.

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Так передавай указатель на сам класс!
Не бойся сделать лишнюю обёртку в виде абстрактного класса с единственным методом.
И от него наследовать класс A и другие в дальнейшем
1
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
13.11.2012, 05:17
Цитата Сообщение от Avazart Посмотреть сообщение
И от него наследовать класс A ... Z
А почему бы и нет? В той же джаве дофига мелких классов бывает объявляется.
Но главное, если ему потребовался указатель на функцию-член и таких функций действительно от A() до Z(), неужели ты думаешь, что создавать эти 26 функций намного легче, чем 26 классов-наследников?

Добавлено через 6 минут

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Поясню указатель на метод и указатель на ф-цию - разные вещи...
Указатель на метод - это смещение члена относительно класса.
Эй, тут другое было

0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 05:17
Цитата Сообщение от ps10n1ck Посмотреть сообщение
и есть какой-то класс (как называется неизвестно), в котором есть метод X или Y, или Z - в общем заранее не известно как этот метод будет называться. Все, что мне нужно сделать, это в метод b() класса B передать некий метод с другого класса.
Наверное невнимательно читаю ...

Перечитав понял следующие - не тип класса ни само имя метода неизвестно заранее так ?

Если б имя метода было одно и тоже то достаточно было зашаблонить
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
//---------------------------------------------------------------------------
class A
{
public:
        void a() { std::cout << "hello! A\n"; };
};
//---------------------------------------------------------------------------
class C
{
public:
        void a() { std::cout << "hello C!\n"; };
};
//---------------------------------------------------------------------------
class B
{
public:
        template<class T> void b(T* t)
        {
            t->a();
        };
};
//---------------------------------------------------------------------------
int main()
{
        A* a = new A;
        B* b = new B;
        C* c = new C;
 
        b->b(a);
        b->b(c);
 
        delete a,b,c;
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
0
 Аватар для ps10n1ck
56 / 50 / 11
Регистрация: 10.11.2010
Сообщений: 132
13.11.2012, 05:24  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Наверное невнимательно читаю ...

Перечитав понял следующие - не тип класса ни само имя метода неизвестно заранее так ?

Если б имя метода было одно и тоже то достаточно было зашаблонить
Да, не тип класса не имя метода неизвестно, в том то и вся беда. Если бы имена были одинаковыми, то можно было бы через шаблон как Вы и писали.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 05:27
Т.е. нужно что-то вроде адаптера, прослойки между классами A1...AX и B

Ну а хоть тип(сигнатура) самого метода один и тот же ?
0
 Аватар для ps10n1ck
56 / 50 / 11
Регистрация: 10.11.2010
Сообщений: 132
13.11.2012, 05:31  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Т.е. нужно что-то вроде адаптера, прослойки между классами A1...AX и B

Ну а хоть тип(сигнатура) самого метода один и тот же ?
Да сигнатура у них одинаковая, только имена методов неизвестны.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 05:32
Мм а что если совместить пример rangerx и шаблоны ?
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,536
Записей в блоге: 1
13.11.2012, 05:33
Цитата Сообщение от ps10n1ck Посмотреть сообщение
Да, не тип класса не имя метода неизвестно, в том то и вся беда. Если бы имена были одинаковыми, то можно было бы через шаблон как Вы и писали.
А что это за такая задача, что требуется передать то, незнаю что? Можно о задаче подробнее?

Почему наследование не желаешь применять?
Сколько всего этих различных методов, на которые будешь брать указатели?
Я настоятельно рекомендую наследование.
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
class aMethodHolder{
public:
virtual void a() =0;
};
 
class A: public aMethodHolder
{
public:
        void a() { std::cout << "hello! A\n"; };
};
//---------------------------------------------------------------------------
class C: public aMethodHolder
{
public:
        void a() { std::cout << "hello C!\n"; };
};
class B
{
public:
        void b(aMethodHolder* t)
        {
            t->a();
        };
};
Но мне действительно непонятно, что не устраивает???
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 05:38
Вот так вот как-то:

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
//---------------------------------------------------------------------------
class A1
{
public:
        void func1()
            {
                std::cout << "hello #1!" << std::endl;
            }
};
//---------------------------------------------------------------------------
class A2 {
 
public:
        void func21()
            {
                std::cout << "hello #2.1!" << std::endl;
            }
        void func22()
            {
                std::cout << "hello #2.2!" << std::endl;
            }
};
//---------------------------------------------------------------------------
class B
{
public:
        template<class T> void func(void (T::*pfunc)(), T& obj)
            {
                (obj.*pfunc)();
            }
};
//---------------------------------------------------------------------------
int main()
{
        A1* a1_obj = new A1;
        A2* a2_obj = new A2;
 
        B* b_obj = new B;
 
        b_obj->func(&A1::func1, *a1_obj);
        b_obj->func(&A2::func21, *a2_obj);
        b_obj->func(&A2::func22, *a2_obj);
 
        delete a1_obj, a2_obj, b_obj;
 
system("pause");
return 0;
}
//---------------------------------------------------------------------------
2
 Аватар для ps10n1ck
56 / 50 / 11
Регистрация: 10.11.2010
Сообщений: 132
13.11.2012, 05:47  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Вот так вот как-то:
Это то, что нужно. Спасибо!
0
13.11.2012, 16:06

Не по теме:

Avazart, оператор delete может принимать только один аргумент. Т.е. в
delete a1_obj, a2_obj, b_obj;
все, что находится после выделенного фрагмента не относится к delete.

1
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
13.11.2012, 19:51
rangerx, Точно...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.11.2012, 19:51
Помогаю со студенческими работами здесь

Указатель на функцию-член класс
Я уже создавал одну тему, но обсуждения проблемы там навело меня еще на один вопрос. Для примера для пояснения возьму код из моего...

Указатель на функцию-член класса
Нужно передать указатель на функцию класса A изнутри самого класса А в функцию, в качестве аргумента классу B. #include...

Указатель на функцию - член класса.
делаю так: class c1 { void foo(); } class c2 { void (*fp)();

Не могу создать указатель на функцию. ошибка: нестандартный синтаксис; используйте "&", чтобы создать указатель на член
Выбивает ошибку, когда хочу присвоить переменной адрес какой то функции. Ошибка в строке 28(если убрать комментарии: 30-33) class...

Не могу создать указатель на перегруженную функцию-член класса
Есть функция монстр из vulkan api. Она является членом класса. Просто написать её название не получается, потому что она перегружена. Каким...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru