2013-06-28 10 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)ServerRunnable के run पर कॉल कर रहा है। जब मैं इसे कंसोल से चलाता हूं तो मुझे लगातार pure virtual method called त्रुटि मिलती है। हालांकि, अगर मैं कोड के माध्यम से gdb stepping में हूँ तो मैं क्लाइंट से कनेक्शन सफलतापूर्वक स्वीकार करूँगा और उन्हें डेटा भेजूंगा। ServerRunnable का run शुद्ध वर्चुअल फ़ंक्शन नहीं है और यही कहा जाना चाहिए। libPoco के थ्रेडिंग के लिए

कोड उदाहरण http://pocoproject.org/slides/130-Threads.pdf

पर मैं भी सोच रहा हूँ कि मैं निर्माता में शुद्ध आभासी विधि बुला जा सकता है, लेकिन contructor में कोई बात नहीं है और मैं बस डिफ़ॉल्ट destuctor उपयोग कर रहा हूँ। क्या वहां कहीं और किस शुद्ध वर्चुअल फ़ंक्शन को बुलाया जा रहा है? जीडीबी में? धन्यवाद।

उत्तर

7

समस्या यह है कि serverIt ऑब्जेक्ट run विधि से पहले गुंजाइश से बाहर हो जाता है।

जब धागा चल सकता है तो आपके पास कोई नियंत्रण नहीं होता है, इसलिए यह हो सकता है कि लूप आपके वर्ग की run विधि से पहले पुनरावृत्त हो जाए, लेकिन फिर आपकी वस्तु नष्ट हो गई है, और इसके विनाश के साथ वर्चुअल फ़ंक्शन टेबल।

+2

मैं मानता हूं कि क्या हो रहा है। सामान्य परिस्थिति जो शुद्ध वर्चुअल फ़ंक्शन को कॉल करने का कारण बनती है वह यह है कि कन्स्ट्रक्टर पूर्ण होने या विनाशक के शुरू होने से पहले वर्चुअल फ़ंक्शन को बुलाया जाता है। –

2
Pool.start() 

धागा और रिटर्न शुरू करता है।

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

आप gdb में यह माध्यम से कदम है, तो आप धागा समय से पहले उदाहरण चर दायरे से बाहर चला जाता है अपनी बात करने के लिए दे: यही कारण है कि पीडीएफ में आप लिंक किए गए उनके ThreadPool उदाहरण इस तरह दिखता है।

संबंधित मुद्दे