forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Укозатель на метод класса (http://forum.boolean.name/showthread.php?t=15353)

den 24.08.2011 23:56

Укозатель на метод класса
 
Имеится некая библиотечная функция, которая принимает в параметры укозатель на функцию:
PHP код:

libfunc(int (*fn)(void *)); 

она вызывается из метода класса MyClass::init, и принемать должна MyClass::someFunc.
Повсякому пробывал - компилятор ругается.
Как?
upd: если не использовать классы, то всё ок.

impersonalis 25.08.2011 00:02

Ответ: Укозатель на метод класса
 
http://forum.boolean.name/showthread.php?t=15043

den 25.08.2011 00:11

Ответ: Укозатель на метод класса
 
видел. читал. непомогает((
PHP код:

SDL_CreateThread(&net::thread, &timeout); 

Цитата:

src/net.cpp:62: error: cannot convert ‘int (net::*)(void*)’ to ‘int (*)(void*)’ for argument ‘1’ to ‘SDL_Thread* SDL_CreateThread(int (*)(void*), void*)’

impersonalis 25.08.2011 00:13

Ответ: Укозатель на метод класса
 
код, где вызваешь покажи
и без смайлов

den 25.08.2011 00:15

Ответ: Укозатель на метод класса
 
кусок файла net.cpp
PHP код:

int net::thread(void *data)
{
    
int timeout = *((int*)data);
    
ENetEvent event;
    while(
enet_host_service(client, &eventtimeout))
    {
        if(
event.type == ENET_EVENT_TYPE_RECEIVE)
        {
            
int size;
            
bytes2int(&(event.packet->data[0]), size);
            for(
int i 0sizei++)
            {
                
pair intint p;
                
bytes2int(&(event.packet->data[sizeof(int)*(i*2+1)]), p.first);
                
bytes2int(&(event.packet->data[sizeof(int)*(i*2+2)]), p.second);
                
SDL_mutexP(lock);
                
v.push_back(p);
                
SDL_mutexV(lock);
            } 
        }
        
enet_packet_destroy(event.packet);
    }
    return 
0;
}

int net::connect(string hostint portint timeout)
{
    
enet_address_set_host(&addresshost.c_str());
    
address.port port;
    
peer enet_host_connect(client, &address2);

    
ENetEvent event;
    if(
enet_host_service(client, &eventtimeout) > && event.type == ENET_EVENT_TYPE_CONNECT)
    {
        
cout << "Connection succeeded" << endl;
    }
    else
    {
        
enet_peer_reset(peer);
        
cerr << "Connection to " << host << ":" << port << " failed" << endl;
        return 
1;
    }
    
SDL_CreateThread(&net::thread, &timeout);
    return 
0;


ps: ошибок больше нет, только эта.

Mr_F_ 25.08.2011 00:17

Ответ: Укозатель на метод класса
 
скорее всего трабла в том, что функция требует в качве параметра глобальную (или статическую) функцию, а ты даёшь нестатический метод.

den 25.08.2011 00:19

Ответ: Укозатель на метод класса
 
описание функции
все методы нестатические.

den 25.08.2011 00:25

Ответ: Укозатель на метод класса
 
сделал тупо приведение:
PHP код:

SDL_CreateThread((int(*)(void*))(&net::thread), &timeout); 

и теперь вместо ошибки предупреждение))
буде тестить

genroelgvozo 25.08.2011 11:35

Ответ: Укозатель на метод класса
 
вообще штатными средствами в си нельзя на нестатичный метод ссылку сделать
это возможно благодаря делегатам, которые есть в других языках, и которые сделал Александреску в си++ с помощью шаблонов, но таким способом, что уж лучше придумать как нибудь без делегатов
об этом написано в его книге, там он много всяких вкусностей, которых нету в си++, сделал с помощью шаблонов

HolyDel 25.08.2011 11:46

Ответ: Укозатель на метод класса
 
делай метод статичным. подумай сам - у какого именно объекта должны вызваться функция, если у тебя их будет 42?

den 25.08.2011 12:02

Ответ: Укозатель на метод класса
 
Цитата:

Сообщение от HolyDel (Сообщение 200077)
делай метод статичным. подумай сам - у какого именно объекта должны вызваться функция, если у тебя их будет 42?

а если через укозатель this ?

genroelgvozo 25.08.2011 12:14

Ответ: Укозатель на метод класса
 
так ведь этот this твоя библиотечная функция и не знает
просто ссылка на метод для всех обьектов одинакова, когда ты вызваешь метод для обьекта ему еще тайно от тебя передается указатель this
и просто так функции этот указатель не передать
и выхода два, либо как казал холидел статик, либо делегат, что в си++ изврат с садомазой))

impersonalis 25.08.2011 15:45

Ответ: Укозатель на метод класса
 
Цитата:

Сообщение от HolyDel (Сообщение 200077)
делай метод статичным. подумай сам - у какого именно объекта должны вызваться функция, если у тебя их будет 42?

Для вызова используются два указателя: на метод и на экземпляр класса. Я же уже писал: http://forum.boolean.name/showthread.php?t=15043

цель:
Код:

class MyCl{
private:
MyStr ControlThread;
void func1(WORD,void*,void*); //<---- хочу вызвать вот это
void func2(WORD,void*,void*);
void func3(WORD,void*,void*);
public:
MyCl();
~MyCl();
}

указтели:
Код:

MyCl *ParentInterface;
void (MyCl::*FunctionPtr)(WORD,void*,void*);

Получение адреса (? вообще костыльно выглядит - фактически по имеющимся данным [без указания конкретного экземпляра класса] можно восстановить только смещение до функции внутри класса, поэтому адрес, вероятно, относительно начала адреса экземпляра) метода (указатель на класс получается как обычно):
Код:

FunctionPtr=&MyCl::func1;
вызов (вызываю функцию с адресом FunctionPtr [здесь это func1] из экземпляра с адресом ParentInterface ):
Код:

(ParentInterface->*FunctionPtr)(0,0,0);

upd поправил код

genroelgvozo 25.08.2011 20:10

Ответ: Укозатель на метод класса
 
этот код работает? или это с++0x уже? я просто новый стандарт не знаю
а то как бы это получаются делегаты через обычный указатель (я думал что в си такое невозможно )
вот статья на хабре как сделать простой делегат на си++ http://habrahabr.ru/blogs/cpp/78299/

UPD
У меня так не работает. Он говорит что функптр должен быть указатель на функцию, а если я его обьявляю как указатель на функцию, он пишет что он должен быть указатель на член))

impersonalis 25.08.2011 21:08

Ответ: Укозатель на метод класса
 
Да, код работает на MSVC++ 6.0 (откуда [год разработки 6-ой сутдии] можно сделать вывод, что это не с++0x).
Повторю ещё раз ссылку на руководство по указателям на функции http://www.newty.de/fpt/index.html

Цитата:

Сообщение от genroelgvozo (Сообщение 200121)
UPD
У меня так не работает. Он говорит что функптр должен быть указатель на функцию, а если я его обьявляю как указатель на функцию, он пишет что он должен быть указатель на член))

Неправильно скопировал, прошу извинить. Ошибка вот здесь (теперь правильно):
Код:

(ParentInterface->*FunctionPtr)(0,0,0);
К сожалению, проверить сейчас не могу, но пример составлен из рабочего кода.


Часовой пояс GMT +4, время: 14:33.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot