2013-06-28 68 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您链接自己的线程池的例子看起来是这样的:

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

当你在gdb一步通了,你给线程的时间做它的事实例变量超出范围了。