Callback и наследование
От: neherim Россия  
Дата: 26.10.10 12:49
Оценка:
Здравствуйте, в программировании я новичок, как решить свою проблему догадываюсь, но не уверен что это решение будет правильным и в стиле c++.

Есть класс сервера, в котором храниться список ссылок на клиентов. Когда клиент принимает информацию от устройства, эта информация должна передаваться через вызов функции HandleRecvData() в класс сервера, где и будет обработана. Адрес функции HandleRecvData(), которая сейчас является статическим методом сервера, я передаю клиенту через конструктор.

Но теперь возникла проблема, мне нужно от сервера наследовать класс, и в нем переопределить функцию HandleRecvData().
Определить ее как виртуальную — не получается, компилятор начинает грязно ругаться. вот теперь сижу и думаю, как это все грамотно "отрефакторить"

typedef void (HandleDataFunc)( const string, const char*, const int);
// класс клиента
class AMClient
{
protected:

    HandleDataFunc*  HandleRecvData;    

public:
    AMClient( SOCKET sSocket, sockaddr_in socket_addr, HandleDataFunc* HandleDataCallback )
    {
        HandleClientEvent    = HandleEventCallback;
        HandleRecvData        = HandleDataCallback;
    }
};

// класс сервера
class AMServer
{
protected:
         list<AMClient*> mClientList;

     static void  HandleRecvData( const string ClientName, const char *pData, const int Size );    
     
     AMClient* CreateClient( SOCKET sSocket, sockaddr_in socket_addr );
public:
    AMServer( const string& pIPAddrStr, unsigned short PortNumber );
    virtual ~AMServer();
};

AMClient* AMServer::CreateClient( SOCKET sSocket, sockaddr_in socket_addr )
{
    return new AMClient( sSocket, socket_addr, HandleRecvData );
}


Единственное что сейчас приходит на ум — сделать функцию CreateClient() виртуальной, и в классе наследнике переопределить ее как-то так:


class AMOpcServer : public AMServer
{
private:
    static void  HandleRecvData2( const string ClientName, const char *pData, const int Size );    

    virtual AMClient* CreateClient( SOCKET sSocket, sockaddr_in socket_addr );
};

AMClient* AMServer::CreateClient( SOCKET sSocket, sockaddr_in socket_addr )
{
    return new AMClient( sSocket, socket_addr, HandleRecvData2 );
}


Но выглядит это совсем ужасно. Ну и собственно вопрос, как сделать это все "in da c++ style"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.