संपादित करें: हलशुद्ध आभासी विधि कहा जाता है
जहां मैं एक आधार कार्यकर्ता वर्ग है मैं एक मल्टी-थ्रेडेड परियोजना पर काम कर रहा हूँ अभी, कार्यकर्ता वर्गों है कि यह से विरासत अलग-अलग। रनटाइम पर, वर्कर क्लासेस थ्रेड बन जाते हैं, जो तब आवश्यकतानुसार काम करते हैं।
अब, मेरे पास एक निदेशक है जिसे मैंने लिखा है जो सभी श्रमिकों को पॉइंटर्स की एक सरणी बनाए रखने के लिए माना जाता है, ताकि वह उनसे जानकारी प्राप्त कर सके, साथ ही बाद में उनके भीतर चर संशोधित कर सके।
baseWorkerClass** workerPtrArray;
तब निदेशक के निर्माता में, मैं गतिशील संकेत की एक सरणी आधार कार्यकर्ता वर्ग के लिए आवंटित:
मैं आधार वर्ग के सूचक के लिए सूचक बनाने के द्वारा ऐसा किया
workerPtrArray = new baseWorkerClass*[numWorkers];
प्रत्येक कार्यकर्ता थ्रेड के निर्माता में, कार्यकर्ता निर्देशक में एक फ़ंक्शन को कॉल करता है जिसका अर्थ उस कार्यकर्ता के सूचक को सरणी में संग्रहीत करना है।
यहाँ कैसे निदेशक संकेत संग्रहीत करता है:
Director::manageWorker(baseWorkerClass* worker)
{
workerPtrArray[worker->getThreadID()] = worker;
}
यहाँ एक कार्यकर्ता संस्करण का एक उदाहरण है। प्रत्येक कर्मचारी को मूल कार्यकर्ता वर्ग से विरासत मिलती है, और आधार कार्यकर्ता वर्ग में शुद्ध वर्चुअल फ़ंक्शंस होते हैं जो सभी कार्यकर्ताओं में मौजूद होना चाहिए, साथ ही साथ कुछ चर जो सभी श्रमिकों के बीच साझा किए जाते हैं।
class baseWorkerClass
{
public:
baseWorkerClass()
{
}
~baseWorkerClass()
{
}
virtual int getThreadID() = 0;
virtual int getSomeVariable() = 0;
};
के बाद प्रत्येक कार्यकर्ता संस्करण आरंभ किया जाता है, मैं baseWorkerClass वस्तुओं की ओर इशारा की एक सरणी के साथ खत्म करना चाहिए:
class workerVariant : protected baseWorkerClass
{
public:
workerVariant(int id)
: id(id)
{
Director::manageWorker(this);
}
~workerVariant()
{
}
int getThreadID()
{
return id;
}
int getSomeVariable()
{
return someVariable;
}
protected:
int id;
int someVariable
};
फिर baseWorkerClass कुछ इस तरह लग रहा है।
workerPtrArray[5]->getSomeVariable(); // Get someVariable from worker thread 5
समस्या है कि इस कोड एक कारण बनता है: यह मैं करने के लिए, उदाहरण के लिए, किसी दिए गए चर का मान एक निश्चित कार्यकर्ता में सरणी सूचकांक के रूप में अपनी आईडी का उपयोग कर, तो तरह मिल में सक्षम होना चाहिए मतलब है एक Windows निष्पादन में दुर्घटना, क्यों, और लिनक्स में, यह कहते हैं की किसी भी विवरण के बिना:
बुलाया
शुद्ध आभासी विधि एक सक्रिय अपवाद
गर्भपात के बिना बुलाया समाप्त
मैं शपथ ले सकता था कि मैंने कुछ समय पर यह काम किया था, इसलिए मैं उलझन में हूं कि मैंने क्या खराब कर दिया है।
वास्तविक असंशोधित कोड समस्या है जो:
कार्यकर्ता संस्करण हैडर: http://pastebin.com/f4bb055c8
कार्यकर्ता संस्करण स्रोत फ़ाइल: http://pastebin.com/f25c9e9e3
बेस कार्यकर्ता वर्ग हैडर: http://pastebin.com/f2effac5
बेस कार्यकर्ता वर्ग स्रोत फ़ाइल: http://pastebin.com/f3506095b
निदेशक शीर्षलेख: http://pastebin.com/f6ab1767a
निदेशक स्रोत फ़ाइल: http://pastebin.com/f5f460aae
संपादित करें: अतिरिक्त जानकारी, manageWorker समारोह में, मैं सूचक से शुद्ध आभासी कार्यों के किसी भी कॉल कर सकते हैं "कार्यकर्ता," और यह सिर्फ ठीक काम करता है। प्रबंधन वर्कर फ़ंक्शन के बाहर, जब मैं पॉइंटर सरणी का उपयोग करने का प्रयास करता हूं, तो यह विफल हो जाता है।
संपादित करें: अब जब मैं इसके बारे में सोचता हूं, थ्रेड का प्रवेश बिंदु ऑपरेटर() है। निदेशक धागे श्रमिकों के सामने बनाया गया है, जिसका अर्थ यह हो सकता है कि अधिभारित कोष्ठक ऑपरेटर शुद्ध वर्चुअल फ़ंक्शंस को कॉल कर रहा है इससे पहले कि उन्हें बाल कक्षाओं द्वारा ओवरराइड किया जा सके। मैं इसमें देख रहा हूँ
इनपुट के लिए धन्यवाद। असल में, getThreadID विधि के बारे में, यह मेरे हिस्से पर सिर्फ एक असंगतता थी। यह वास्तविक कोड नहीं है जिसका मैं उपयोग कर रहा हूं, यह केवल कुछ चीजें हैं जो मैंने कुछ मिनट पहले स्पष्ट रूप से और संक्षेप में मेरे बिंदु को स्पष्ट करने के लिए लिखा था। getThreadID विधि _is_ शुद्ध वर्चुअल, और _is_ प्रत्येक कार्यकर्ता संस्करण में ओवरराइड किया गया है। सभी getThreadID विधि थ्रेड के "आईडी" चर को वापस कर देता है। – jakogut
जब कोई ऑब्जेक्ट निर्माणाधीन होता है (जब कन्स्ट्रक्टर निष्पादित किया जाता है), वर्चुअल फ़ंक्शन तंत्र ऑब्जेक्ट के प्रकार से प्राप्त कक्षा के आभासी कार्यों में कभी भी कॉल नहीं करेगा। ऐसा इसलिए है क्योंकि व्युत्पन्न कक्षाओं के रचनाकारों को अभी तक निष्पादित नहीं किया गया है।इसलिए कन्स्ट्रक्टर से व्युत्पन्न क्लास विधि को कॉल करना काम नहीं करेगा। इनमें से एक तरीका दो चरण का निर्माण है, अधिमानतः एक रैपर ऑब्जेक्ट के पीछे छिपा हुआ है। (विनाश के लिए वही है, बीटीडब्ल्यू।) – sbi
ओह, बकवास, तुम सही हो, मैंने इसके बारे में नहीं सोचा था। मुझे यहां एक त्वरित परीक्षण करने दें, और मैं वापस रिपोर्ट करूंगा। (नींद का एक और घंटा चला जाता है।) – jakogut