Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Проблемы с указателем на функцию


Автор: DeadProger 25.5.2005, 21:57
Есть некий класс TheClass ; В классе есть указатель на функцию: void (*pfunc)(void), и есть некая функция этого класса void some_func(void); Проблема в том, что нужно этому указателю присвоить адрес этой функции, а компилятор возмущается, и
в ответ на pfunc=some_func; пишет примерно следующее:
cannot convert from 'void (__thiscall TheClass::*)(void )' to 'void (__cdecl *)(void)'

Как можно это обойти?
Хелп плиз

Автор: Coocky 25.5.2005, 22:03
DeadProger
Код дай!
Компилятор пишет что не может преобразовать

Автор: kometa_triatlon 25.5.2005, 22:11
pfunc=some_func;

А где ты это вызываешь? Если вне класса, тогда нужно так:
Код

TheClass Class;
pfunc=Class.some_func();

Автор: DeadProger 25.5.2005, 22:15
Сам код сильно громоздкий, так что вот псевдо:

Код

class TheClass
{
public:
   TheClass();
   virtual ~TheClass();

void (*pfunc)(void);

void some_func(void);

void Init(void);

};

TheClass::TheClass(){}
TheClass::~TheClass(){}

void TheClass::Init(void)
{
  pfunc=some_func;
}

void TheClass::some_func(void)
{

}


И ошибка, которую он вызывает:
error C2440: '=' : cannot convert from 'void (__thiscall TheClass::*)(void)' to 'void (__cdecl *)(void)'

Автор: jorkug 26.5.2005, 04:09
Может так:?
Код

pfunc=( void(__cdecl *)(void) )some_func;

Автор: kometa_triatlon 26.5.2005, 04:47
Не работает...

Автор: Mayk 26.5.2005, 06:20
Функция должна быть статической.

Вы думаете что ей ничего не передается в качестве параметров, т.к. написано void somefunc(void)? Но С++ придерживается иного мнения на этот счет.
this. Он тоже является ОБЫЧНЫМ параметром. Он даже не всегда заметен, но согласитесь, что
Код

void Foo::incBar(void)
{
    bar++;
}

это то же самое, что и
Код

void Foo::incBar(void)
{
    this->bar++;
}

(подразумевается, что bar не статическая переменная)

Дизассемблируйте любую программу и увидите, что первый параметр любой функции класса (это последний параметр, пихаемый в стек) является указателем на сам класс, если, конечно, компиляторы не были сильно умны, чтобы понять ненужность this в некоторых случаях. Однако, someFunc в исходной задачи это не просто функция. Это член класса(метод класса, если хотите). И получается этот метод вот так:

Код

void (ThisClass::*pfunc)(void);
pfunc = &ThisClass::some_func;


А вызывается вообще зверски:

Код

    ThisClass this_class;
    (this_class.*pfunc)(); //(this_class->*pfunc)() если this_class был бы указателем


По-моему легче объявить функцию статической. Если нужны данные, то добавить явный аргумент this (лично мне нравится имя self: так назывался текущий объект в QuakeC)
Код

class ThisClass{
    public:
    static void some_func(ThisClass* self) {self->blahblah *= 2;};
    private:
    int blahblah;
}

Кстати, важно заметить то, что если some_func определена как функция класса(как в примере), то она имеет доступ к закрытым/private данным этого класса, в отличии от функции объявленной вне класса.



Автор: Vyacheslav 26.5.2005, 09:16
Код

class TheClass
{
public:
   TheClass();
   virtual ~TheClass();

void (TheClass::*pfunc)(void);

void some_func(void);

void Init(void);

};

TheClass::TheClass(){}
TheClass::~TheClass(){}

void TheClass::Init(void)
{
  pfunc=&TheClass::some_func;
}

void TheClass::some_func(void) {} 
 

Автор: DeadProger 26.5.2005, 21:23
Vyacheslav Тогда возникает другая проблема:
как теперь вызвать функцию через этот указатель? Компилер позволяет использовать указатель void (TheClass::*pfunc)(void) только как часть данных:
TheClass *obj=new TheClass;
obj->Init();
obj->pfunc();//Ошибка: term doesn't evaluate to the function
obj->pfunc;//Нет ошибки


Автор: Void 26.5.2005, 21:40
DeadProger
Код

(obj->*pfunc)();

Автор: DeadProger 26.5.2005, 21:44
Void
error C2065: 'pfunc' : undeclared identifier
error C2297: '->*' : illegal, right operand has type 'int'

Автор: Void 26.5.2005, 21:55
DeadProger
Весь код в студию. Вот так оно используется:
Код

class A {
public:
    void f() {}
};

void (A::*pf)(); // pf - указатель на функцию-член класса A
pf = &A::f; // инциализируем указатель
A *t = new A; 
(t->*pf)(); // эквивалентно t->f()

Автор: DeadProger 26.5.2005, 22:02
Пасиба

Автор: Mayk 27.5.2005, 04:51
Цитата

Код

    void (ThisClass::*pfunc)(void); 
    pfunc = &ThisClass::some_func;

А вызывается вообще зверски:
Код

    ThisClass this_class;
    (this_class.*pfunc)(); //(this_class->*pfunc)() если this_class был бы указателем



Я сейчас обижусь и уйду в монастырь молить Бьярна чтобы мои ответы читали

Автор: Vyacheslav 27.5.2005, 09:11
Mayk А обижаться нечего. Большинство ваших ответов представляют обширные по объему декларации общеизвестных истин, из которых довольно трудно найти ответ на вопрос. Например, я прочитав ваше вступление про скрытый параметр this и про то, что лучше использовать статические методы, тоже совершенно пропустил то, что могло бы быть с натяжкой принято за ответ. Поэтому и дал свой вариант, без сентенций. И он, как оказалось, был более доходчив smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)