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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.76
therom
Сообщений: n/a
#1

Ссылки на функции класса - C++

30.09.2008, 16:21. Просмотров 2706. Ответов 10
Метки нет (Все метки)

Задача:
В классе иметь массив ссылок на функции этого класса, чтобы вызывать их по номеру из массива.
Также в классе должна присутствовать функция обработки массива с целью получения ссылки на функции (по номеру в массиве) и их вызова.
Например: нужно вызвать функцию №2 класса MyClass........
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef void (*PF)(void); //Это для ссылки на функцию
// Есть класс:
class MyClass
{
public:
void func1(void){}
void func2(void){}
 
PF massiv[2]; // создаем массив ссылок для функций 
 
MyClass(void) // Конструктор
{
// в конструкторе присваиваем ссылкам адреса функций
massiv[0]=&func1;
massiv[1]=&func2;
}
};
Выскакивает ошибка в строках конструктора:
Error[Pe144]: a value of type "void (__nearfunc __version_3 MyClass::*)(void)" cannot be used to initialize an entity of type "PF"

Насколько я понял: на стадии конструирования класса еще не известны точные адреса функций

Приняв это предположение как факт, я попытался передать конструктору адрес класса:
C++
1
2
3
4
5
6
MyClass(MyClass* adres) // Конструктор
{
// в конструкторе присваиваем ссылкам адреса функций
massiv[0]=&adres->func1;
massiv[1]=&adres->func2;
}
Теперь выскочила друкая ошибка:
Error[Pe300]: a pointer to a bound function may only be used to call the function

Как правильно реализовать задачу?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.09.2008, 16:21     Ссылки на функции класса
Посмотрите здесь:

C++ Передача класса по ссылки в метод (ругается)
C++ Как описывать функции, заданные в шаблоне класса, тип возвращаемого значения которых совпадает с именем класса
C++ Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса?
Возможно ли создание объекта шаблонного класса в функции этого класса? C++
C++ Какими способами можно использовать функции класса B, как параметры функции Sub класса А?
Как обраиться к функции класса через другую функцию класса (друга)? C++
Создание статической функции класса, которая принимает экземпляр этого же класса как объект C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Lord_Voodoo
Супер-модератор
 Аватар для Lord_Voodoo
8506 / 2173 / 61
Регистрация: 07.03.2007
Сообщений: 10,848
Завершенные тесты: 1
30.09.2008, 16:30     Ссылки на функции класса #2
я писал так, правда это в билдере:
Код
.h:
       void __fastcall CallView(AnsiString Type, AnsiString Caption);
       void __fastcall CallViewP(AnsiString Type, AnsiString Caption);
       void __fastcall (__closure* Func[2])(AnsiString, AnsiString);
.cpp:
  Func[0] = &CallView;
  Func[1] = &CallViewP;
а в других ide __closure не надо, вроде так читал по справке...
Код
typedef void (*PF)(void); //Это для ссылки на функцию
void func1(void){}
void func2(void){}
// Есть класс:
class MyClass
{
public:

PF massiv[2]; // создаем массив ссылок для функций 

MyClass(void) // Конструктор
{
// в конструкторе присваиваем ссылкам адреса функций
massiv[0]=&func1;
massiv[1]=&func2;
}
};
а у себя попробуй вынести реализацию методов отдельно от класса... должно сработать...
Vourhey
Почетный модератор
6471 / 2246 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
30.09.2008, 16:37     Ссылки на функции класса #3
Код
. . .
void (MyClass::*massiv[2])(void); // создаем массив ссылок для функций 

MyClass(void) // Конструктор
{
// в конструкторе присваиваем ссылкам адреса функций
massiv[0]=&MyClass::func1;
massiv[1]=&MyClass::func2;
. . .
XuTPbIu_MuHTAu
Эксперт C++
 Аватар для XuTPbIu_MuHTAu
2220 / 735 / 10
Регистрация: 27.05.2008
Сообщений: 1,507
30.09.2008, 16:40     Ссылки на функции класса #4
Есть огромная разница между функциями,и функциями- членами класса. Функции,описанные в классе,неявно принимают как параметр указатель на класс. Поэтому твое описание типа PF заведомо не рабочее.

Используй такую форму записи:
Код
void (MyClass::*PF)(void);
Lord_Voodoo
Супер-модератор
 Аватар для Lord_Voodoo
8506 / 2173 / 61
Регистрация: 07.03.2007
Сообщений: 10,848
Завершенные тесты: 1
30.09.2008, 17:03     Ссылки на функции класса #5
я тут заметил, что в разных компиляторах разная форма написания такого рода массивов, ты на чем пишешь?
вот так работает в code block:
Код
typedef void (*PF)(void); 
class MyClass
{
public:
  static void MyClass::func1(void){ cout<<"func1"<<endl;};
  static void MyClass::func2(void){ cout<<"func2"<<endl;};
  PF massiv[2]; 
  MyClass(void) {
    massiv[0]=&func1;
    massiv[1]=&func2;
  }
};
therom
Сообщений: n/a
30.09.2008, 19:59     Ссылки на функции класса #6
Далее следует еще одна проблема:
В классе есть функция, вызывающая функции класса по их номеру:
Код
void execute(char number)
{
(this->*massiv[number])();
}
Сдесь все ок.

Вызов извне этого обработчика выглядит так:
Код
MyClass myclass;
char number=1;
myclass.execute(number);
И сдесь все ок.

Проблема возникает, если у меня несколько классов и все разные, а вызывать надо по номеру класса и номеру функции в классе.
Не получается создать массив указателей на разные классы и через него вызывать класс->функцию
qwone
8 / 8 / 1
Регистрация: 18.08.2008
Сообщений: 129
30.09.2008, 22:38     Ссылки на функции класса #7
Цитата Сообщение от therom Посмотреть сообщение
Не получается создать массив указателей на разные классы и через него вызывать класс->функцию
так не создавай массив создавай список .

а вообще массив из разнородных элементов никогда не получается .
а указатели на разные классы и есть разнородные элементы .
Sined
 Аватар для Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
01.10.2008, 00:57     Ссылки на функции класса #8
Цитата Сообщение от qwone Посмотреть сообщение
а вообще массив из разнородных элементов никогда не получается .
Почему не получиться?

Вот пример:
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
class Base
{
public:
    virtual void Test1()=0;
    virtual void Test2()=0;
};
 
class First:public Base
{
public:
    void Test1()
    {
        printf("Test1 from First\n");
    }
    void Test2()
    {
        printf("Test2 from First\n");
    }
};
 
class Second:public Base
{
public:
    void Test1()
    {
        printf("Test1 from Second\n");
    }
    void Test2()
    {
        printf("Test2 from Second\n");
    }
};
 
void main()
{
    void *a[2];
    Base *base1=new First();
    Base *base2=new Second();
    a[0]=base1;
    a[1]=base2;
    if(dynamic_cast<First*>((Base*)(a[0])))
    {
        reinterpret_cast<First*>(a[0])->Test1();
        reinterpret_cast<First*>(a[0])->Test2();
    }
    else
    {
        reinterpret_cast<Second*>(a[0])->Test1();
        reinterpret_cast<Second*>(a[0])->Test2();
    }
    if(dynamic_cast<Second*>((Base*)(a[1])))
    {
        reinterpret_cast<First*>(a[1])->Test1();
        reinterpret_cast<First*>(a[1])->Test2();
    }
    else
    {
        reinterpret_cast<Second*>(a[1])->Test1();
        reinterpret_cast<Second*>(a[1])->Test2();
    }
    delete base1;
    delete base2;
}
Правда заумно, но работает!!!
qwone
8 / 8 / 1
Регистрация: 18.08.2008
Сообщений: 129
01.10.2008, 18:43     Ссылки на функции класса #9
это не разнородные , это родственные , да и то на общую (базовую) часть . Но именно разнородные . Ведь ты это спрашивал?
Sined
 Аватар для Sined
9 / 7 / 2
Регистрация: 30.08.2008
Сообщений: 120
02.10.2008, 00:42     Ссылки на функции класса #10
Цитата Сообщение от qwone Посмотреть сообщение
это не разнородные , это родственные...
Может я и путаю, "разнородные" и "родственные", но классы та разные, и функции я могу описать по-разному, единственное что интерфейс у классов одинаковый.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.10.2008, 22:52     Ссылки на функции класса
Еще ссылки по теме:

C++ Как полю класса А обратится к приватной функции класса А?
Удаление экземпляра класса в функции самого класса (Ошибка при отладке) C++
C++ Ссылки на функции и методы класса
C++ Передача ссылки на обьект класса в функцию
Изменение статического закрытого элемента данных класса посредством статической элемент-функции класса C++

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

Или воспользуйтесь поиском по форуму:
drfaust
256 / 146 / 37
Регистрация: 02.10.2008
Сообщений: 528
Записей в блоге: 1
Завершенные тесты: 1
02.10.2008, 22:52     Ссылки на функции класса #11
Согласен с Sined`ом: если хочеш сделать структуру классов (массив или какую-либо динамику (список, дерево и т.д.)), то работай только через базоваый класс. Вопрос: как полутить доступ к указателям на функции-члены класса из глобального пространства имён: 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
31
32
33
# include "stdlib.h"
 
class Base //базовый класс - нужен для "общности" классов (поэтому pure virtual)
{public:
   virtual int value()=0; // "вес" этого класса
};
 
class A: public Base //один потомок
{public:
  int value(); // вычисляется по одному Палгоритму :)
};
 
class B: public Base //другой потомок
{ public:
  int value(); // вычисляется по другому алгоритму
};
 
Base array[234]={...,...,...}; // какой-то массив классов (и A, и B)
 
#typedef int (*PF)(void); //Это для ссылки на функцию
 
void PrintLess(PF func1, PF func2); //что-то делает за счёт func1 и func2
 
int main(int,char**)
{
 PrintLess(PF func1, PF func2);
 return 0;
}
 
void PrintLess(PF func1, PF func2)
{
....
}
Такая ситуация возникает если используешь библиотечные С-функции применительно к функциям-членам классов: была проблема установить обработчик прерывания на функцию-член "стандартным способом": setvect() в BC 3.1 для MS DOS. Пришлось решать через функцию-static-член и один глобальный указатель на неё... Коряво, не красиво, но это единственное,что я нашёл
Yandex
Объявления
02.10.2008, 22:52     Ссылки на функции класса
Ответ Создать тему
Опции темы

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