एक जटिल codebase में, मैं गैर आभासी आधार वर्ग सूचक (आधार वर्ग कोई आभासी तरीकों है) की एक सरणी हैसी ++ असुरक्षित डाली वैकल्पिक हल
इस कोड पर विचार करें:
#include <iostream>
using namespace std;
class TBase
{
public:
TBase(int i = 0) : m_iData(i) {}
~TBase(void) {}
void Print(void) {std::cout << "Data = " << m_iData << std::endl;}
protected:
int m_iData;
};
class TStaticDerived : public TBase
{
public:
TStaticDerived(void) : TBase(1) {}
~TStaticDerived(void) {}
};
class TVirtualDerived : public TBase
{
public:
TVirtualDerived(void) : TBase(2) {}
virtual ~TVirtualDerived(void) {} //will force the creation of a VTABLE
};
void PrintType(TBase *pBase)
{
pBase->Print();
}
void PrintType(void** pArray, size_t iSize)
{
for(size_t i = 0; i < iSize; i++)
{
TBase *pBase = (TBase*) pArray[i];
pBase->Print();
}
}
int main()
{
TBase b(0);
TStaticDerived sd;
TVirtualDerived vd;
PrintType(&b);
PrintType(&sd);
PrintType(&vd); //OK
void* vArray[3];
vArray[0] = &b;
vArray[1] = &sd;
vArray[2] = &vd; //VTABLE not taken into account -> pointer not OK
PrintType(vArray, 3);
return 0;
}
उत्पादन होता है (Win64 पर Mingw-W64 जीसीसी 4.9.2 के साथ संकलित):
Data = 0
Data = 1
Data = 2
Data = 0
Data = 1
Data = 4771632
विफलता के कारण TVirtualDerived के प्रत्येक उदाहरण वर्चुअल टेबल, जो TBase नहीं है करने के लिए एक सूचक होता है। तो पिछली प्रकार की जानकारी के बिना टीबीएएस को अप-कास्टिंग (शून्य * से टीबीज़ * तक) सुरक्षित नहीं है।
बात यह है कि मैं पहले स्थान पर शून्य * कास्टिंग से बच नहीं सकता। आधार वर्ग काम करता है पर एक आभासी विधि (उदाहरण के लिए नाशक) जोड़ना है, लेकिन एक स्मृति लागत (जो मैं से बचना चाहते हैं) पर
प्रसंग:
हम एक संकेत/स्लॉट प्रणाली को लागू कर रहे हैं एक बहुत ही में, बाधित वातावरण (स्मृति गंभीर रूप से सीमित)।
मैं कैसे इस समस्या को हल कर सकते हैं: जब से हम कई लाखों लोगों की वस्तु जो भेजने के लिए या संकेतों को प्राप्त कर सकते हैं, अनुकूलन के इस प्रकार प्रभावी (जब यह निश्चित रूप से, काम करता है)
प्रश्न है? अब तक, मैंने पाया है:
1 - टीबीज़ में वर्चुअल विधि जोड़ें। काम करता है, लेकिन यह वास्तव में समस्या को हल नहीं करता है, यह इससे बचाता है। और यह अक्षम है (बहुत अधिक स्मृति)
2 - सामान्यता के नुकसान की कीमत पर, सरणी में शून्य * को कास्टिंग करने के बजाय टीबीज़ * कास्टिंग। (शायद मैं आगे क्या कोशिश करूंगा)
क्या आप एक और समाधान देखते हैं?
आपकी संतुष्टि के लिए समस्या को सुलझाने के लिए 'शून्य * * पर कास्टिंग करने से पहले' टीबीएस * * * पर कास्टिंग करना होगा? ([यहां देखें] (https : //ideone.com/kpNhe6)) –
बस स्पष्ट होना: आपके कुछ व्युत्पन्न वर्गों में वर्चुअल विधियां हैं। अन्य नहीं करते हैं। और टीबेस खुद इतना छोटा है कि एक vtable सूचक जोड़ने मेमोरी आकार में एक महत्वपूर्ण वृद्धि का कारण बनता है। सही बात? –
क्या आपने टेम्पलेट का उपयोग करने पर विचार किया है? – cup