Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с указателем на функцию 
:(
    Опции темы
DeadProger
Дата 25.5.2005, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 30.12.2004
Где: The Earth

Репутация: нет
Всего: нет



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

Как можно это обойти?
Хелп плиз
PM MAIL   Вверх
Coocky
Дата 25.5.2005, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GUI гуру
****


Профиль
Группа: Участник Клуба
Сообщений: 2879
Регистрация: 16.2.2004
Где: Украина. Запорожь е

Репутация: 2
Всего: 62



DeadProger
Код дай!
Компилятор пишет что не может преобразовать


--------------------
Верю в смерть после жизни, в любовь после секса ,в крем после бритья smile        
PM ICQ   Вверх
kometa_triatlon
Дата 25.5.2005, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 384
Регистрация: 7.1.2005
Где: Киев

Репутация: 2
Всего: 6



pfunc=some_func;

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

TheClass Class;
pfunc=Class.some_func();



--------------------
Всё очень просто: сказки обман,
Солнечный остров скрылся в туман,
Замков воздушных не носит земля,
Кто-то ошибся, ты или я.

--------------
Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым.
PM MAIL ICQ   Вверх
DeadProger
Дата 25.5.2005, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 30.12.2004
Где: The Earth

Репутация: нет
Всего: нет



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

Код

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)'
PM MAIL   Вверх
jorkug
Дата 26.5.2005, 04:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 21.3.2005

Репутация: нет
Всего: 1



Может так:?
Код

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

PM MAIL   Вверх
kometa_triatlon
Дата 26.5.2005, 04:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 384
Регистрация: 7.1.2005
Где: Киев

Репутация: 2
Всего: 6



Не работает...



--------------------
Всё очень просто: сказки обман,
Солнечный остров скрылся в туман,
Замков воздушных не носит земля,
Кто-то ошибся, ты или я.

--------------
Программирование - самое большое удовольствие, которое вы можете получить, будучи одетым.
PM MAIL ICQ   Вверх
Mayk
Дата 26.5.2005, 06:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Функция должна быть статической.

Вы думаете что ей ничего не передается в качестве параметров, т.к. написано 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 данным этого класса, в отличии от функции объявленной вне класса.





--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 26.5.2005, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Код

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) {} 
 



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
DeadProger
Дата 26.5.2005, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 30.12.2004
Где: The Earth

Репутация: нет
Всего: нет



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


PM MAIL   Вверх
Void
Дата 26.5.2005, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



DeadProger
Код

(obj->*pfunc)();



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
DeadProger
Дата 26.5.2005, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 30.12.2004
Где: The Earth

Репутация: нет
Всего: нет



Void
error C2065: 'pfunc' : undeclared identifier
error C2297: '->*' : illegal, right operand has type 'int'

PM MAIL   Вверх
Void
Дата 26.5.2005, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



DeadProger
Весь код в студию. Вот так оно используется:
Код

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

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



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
DeadProger
Дата 26.5.2005, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 30.12.2004
Где: The Earth

Репутация: нет
Всего: нет



Пасиба
PM MAIL   Вверх
Mayk
Дата 27.5.2005, 04:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата

Код

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

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

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



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


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 27.5.2005, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



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



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1126 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.