में मिश्रण-इन्स के साथ उत्सुक परिपत्र विरासत यहां परिपत्र विरासत को अनसुलझा करने का एक अच्छा तरीका क्या है?C++
class Node {
// ...
public:
list<Node*> neighbors() { /* ... */ }
void update() { }
}
template<class NodeType>
class HasImportance : public virtual NodeType {
double m_importance = 0.0;
public:
void receive_importance(double imp) { /* ... */ }
void give_importance() {
for (auto neighbor : this->neighbors())
neighbor->receive_importance(m_importance /* ... */);
}
};
class TrafficLight : public HasImportance<TrafficLight>, virtual Node {
public:
list<TrafficLight*> neighbors() { ... }
void update() { give_importance(); /* ... */ }
};
यह (जीसीसी 4.7.0) में विफल रहता है क्योंकि TrafficLight
जब HasImportance
की कोशिश करता यह से प्राप्त करना एक अधूरी प्रकार है।
वास्तविक समस्या यह है कि हैसपोर्ट को neighbors()
द्वारा लौटाए गए प्रकार को जानने की आवश्यकता है। Node
से HasImportance
इनहेरिट करती है, तो यह neighbors()
रिटर्न TrafficLight*
Node*
की एक सूची, नहीं सोचता है, और फलस्वरूप पता नहीं है कि यह आइटम पर receive_importance()
फोन कर सकते हैं। HasImportance
पर समान समस्या का वारिस नहीं है।
बीटीडब्ल्यू, जो मैं करने की कोशिश कर रहा हूं वह विभिन्न प्रकार के ग्राफ को आसानी से परिभाषित करने में मदद करने के लिए कुछ मिश्रण-इन्स बनाता है और अलग-अलग मिश्रण में यूनिट-टेस्ट को अलग-अलग करता है। उदाहरण के लिए, मुझे लिखकर class TrafficLight : public HasImportance, HasState<3>, virtual Node { }
लिखकर यातायात रोशनी के ग्राफ के लिए नोड क्लास को परिभाषित करने में सक्षम होना चाहिए।
मैं इसे हल करने के तीन तरीकों से आया हूं, लेकिन सभी बदसूरत लगते हैं। (1) static_cast<NodeType*>
। (2) TrafficLight
अपने कन्स्ट्रक्टर में this
से HasImportance
पास करता है। इस तरह, HasImportance
को वारिस की आवश्यकता नहीं है; यह सिर्फ पॉइंटर से (एहेम) स्टोर करता है, और टेम्पलेट पैरामीटर पॉइंटर का प्रकार प्रदान करता है। (3) बनाने Node
एक वर्ग टेम्पलेट, इस तरह:
template<class NodeType>
class Node {
public:
list<NodeType*> neighbors() { /* ... */ }
}
class TrafficLight : public HasImportance<Node<TrafficLight>> { /* ... */ }
संकलित यही कारण है कि और यह this
, के एक नि: शुल्क प्रतिलिपि परिचय नहीं है लेकिन ऐसा लगता है ... कुछ ज़्यादा ही उत्सुक।
क्या यहां कोई कोड गंध है? क्या मुझे इन ग्राफों को पूरी तरह से अलग-अलग तरीके से देखना चाहिए?
'static_cast (यह)' सीआरटीपी में सामान्य * का उपयोग कर रहा है। –
kennytm
@ केनीटीएम: मैं अब तक भी जाऊंगा और कहूंगा कि यह सीआरटीपी – PlasmaHH
धन्यवाद का उपयोग करने में महत्वपूर्ण है। मैं static_cast का उपयोग करने पर क्रिंग करता हूं, क्योंकि ऐसा लगता है कि मैं एक संकेत (एक "गंध") को अनदेखा कर रहा हूं कि कुछ गहरा गलत है। यदि यह सीआरटीपी में "सामान्य" है, तो मुझे लगता है कि मैं इतना विरोध नहीं करूँगा। यह मेरा पहला सीआरटीपी है। क्या तुम बता सकते हो? :) –