2013-06-28 2 views
5

Я использую libPoco для создания фиктивного сервера для проверки кода клиента.Как называется виртуальная функция

class ServerRunnable: public Poco::Runnable { 
    public: 
ServerRunnable(StreamSocket conn) : conn(conn) { 
} 

void run(){ 
    string mess("Can you hear me?\n"); 
    try{ 
    this->conn.sendBytes(mess.c_str(), mess.size()); 
    } catch (Poco::Exception& ex){ 
    cerr << ex.displayText() << endl; 
    return; 
    } 
    cerr << "The message has been sent." << endl; 
} 

void setConn(StreamSocket inConn){ 
    this->conn = inConn; 
} 
    private: 
StreamSocket conn; 
}; 


int main(int argc, char **argv){ 
    ServerSocket s; 
    try{ 
    s.bind(8083, true); 
    } catch (Exception &ex){ 
    cerr << ex.displayText() << endl; 
    exit(1); 
    } 
    s.listen(124); 

    Poco::ThreadPool Pool(10, 25, 60, 128); 
    while(1){ 
    try{ 
     StreamSocket conn = s.acceptConnection(); 
     ServerRunnable serveIt(conn); 

     Pool.start(serveIt); 
    } catch (Exception &ex){ 
     cerr << ex.displayText() << endl; 
     Pool.joinAll(); 
     exit(1); 
    } 
    } 
    return 0; 
} 

Poco::Runnable является абстрактным классом, и я уверен, что бег является чисто виртуальной функцией. Pool.start(serveIt), похоже, вызывает ServerRunnablerun. Когда я запускаю его с консоли, я постоянно получаю ошибку pure virtual method called. Однако, если я нахожусь в gdb, перешагнув код, я буду успешно принимать соединение с клиентом и отправлять им данные. ServerRunnablerun не является чистой виртуальной функцией, и это то, что нужно назвать.

примеры кода для нарезания резьбы libPoco находятся в http://pocoproject.org/slides/130-Threads.pdf

Я также думаю, что я мог бы называть чисто виртуальный метод в конструкторе, но нет ничего в застройщик, и я просто с помощью destuctor по умолчанию. Есть ли что-то, чтобы прибить место и какую чистую виртуальную функцию вызывается? В gdb? Благодарю.

ответ

7

Проблема, скорее всего, что вы serverIt объект выходит за пределы области до того, как будет вызван метод run.

У вас нет контроля над тем, когда поток может выполняться, поэтому может быть, что цикл повторяется до того, как будет вызван метод вашего класса, вызываемый вашим классом, но затем ваш объект был уничтожен и с его уничтожением, конечно таблицу виртуальных функций.

+2

Я согласен, что, скорее всего, что происходит. Общим обстоятельством, вызывающим чистую виртуальную функцию, является то, что виртуальная функция вызывается либо до завершения конструктора, либо после начала деструктора. –

2
Pool.start() 

начинает тему и возвращается. Вот почему в PDF вы связали их ThreadPool примера выглядит следующим образом:

main() 
    Poco::ThreadPool::defaultPool().start(runnable); 
    Poco::ThreadPool::defaultPool().joinAll(); 
    return 0; 

Когда вы шаг через него в GDB, вы даете время нити, чтобы сделать свое дело до того, как переменная экземпляра выходит из области видимости.