मैं आज एक समस्या में ठोकर खाई कि मैं हल नहीं कर सकता। मैं एक साझा लाइब्रेरी संकलित कर रहा हूं जिसमें एक टेम्पलेटेड क्लास (Derived<T>
, जिसका आधार Base
है) और इस वर्ग के कुछ स्पष्ट तत्कालताएं शामिल हैं। मैं लाइब्रेरी उपयोगकर्ता को इस टेम्पलेटेड क्लास से विस्तार करना चाहता हूं। समस्या तब उत्पन्न होती है जब मैं dynamic_cast
उपयोगकर्ता का उदाहरण Base*
से Derived<T>*
पर करता हूं।एक साझा लाइब्रेरी में एक टेम्पलेटेड क्लास और गतिशील_कास्ट की स्पष्ट तत्कालता
साझा लाइब्रेरी निम्न फ़ाइलें हैं::
Base.h
#ifndef BASE_H_
#define BASE_H_
class Base {
public:
Base();
virtual ~Base();
};
#endif /* BASE_H_ */
Derived.h
मैं इस मेगावाट करने के लिए समस्या को संकुचित होता है
#ifndef DERIVED_H_
#define DERIVED_H_
#include <Base.h>
template <typename T>
class Derived : public Base {
public:
Derived();
virtual ~Derived();
};
#endif /* DERIVED_H_ */
,210
Derived.cpp
#include <Derived.h>
template <typename T>
Derived<T>::Derived() :
Base() {
}
template <typename T>
Derived<T>::~Derived() {
}
// explicit instantiations
template class Derived<float>;
template class Derived<double>;
template class Derived<long double>;
Helper.h
#ifndef HELPER_H_
#define HELPER_H_
#include <Base.h>
class Helper {
public:
Helper(Base* m);
virtual ~Helper();
};
#endif /* HELPER_H_ */
Helper.cpp
#include <Helper.h>
#include <Base.h>
#include <Derived.h>
#include <iostream>
using namespace std;
Helper::Helper(Base* m) {
cout << "after received " << m << endl;
cout << "after fom: " << dynamic_cast< Derived<float>* >(m) << endl;
cout << "after dom: " << dynamic_cast< Derived<double>* >(m) << endl;
cout << "after ldom: " << dynamic_cast< Derived<long double>* >(m) << endl;
cout << "===" << endl;
}
Helper::~Helper() {
}
और एक सरल कोड का उपयोग करता है पुस्तकालय हो सकता है:
test.cpp
#include <Derived.h>
#include <Helper.h>
#include <iostream>
using namespace std;
class MyModel : public Derived<double> {
public:
MyModel() : Derived<double>() {
};
virtual ~MyModel() {
};
};
int main(int argc, char *argv[]) {
MyModel om1;
cout << "created mymodel " << &om1 << endl;
cout << "before fom: " << dynamic_cast< Derived<float>* >(&om1) << endl;
cout << "before dom: " << dynamic_cast< Derived<double>* >(&om1) << endl;
cout << "before ldom: " << dynamic_cast< Derived<long double>* >(&om1) << endl;
cout << "===" << endl;
Helper root(&om1);
return 0;
}
समस्या यह है कि जब मैं एक शेयर की गई लाइब्रेरी और इसके खिलाफ कड़ी test.cpp
बनाने के लिए, dynamic_cast
विफल रहता है।
created mymodel 0x7fff5fbff3e0
before fom: 0
before dom: 0x7fff5fbff3e0
before ldom: 0
===
after received 0x7fff5fbff3e0
after fom: 0
after dom: 0 // <<< Here I expected it to succeed and return a non-null pointer
after ldom: 0
===
, अगर मैं एक साथ पूरे पुस्तकालय और उदाहरण संकलन, कलाकारों सफल होता है हालांकि:
created mymodel 0x7fff5fbff3e0
before fom: 0
before dom: 0x7fff5fbff3e0
before ldom: 0
===
after received 0x7fff5fbff3e0
after fom: 0
after dom: 0x7fff5fbff3e0
after ldom: 0
===
मेरा प्रश्न है: क्यों dynamic_cast
में नाकाम रहने के है यहाँ एक उदाहरण उत्पादन है?
और, इस आधार पर कि मैं उदाहरण की तरह एक वर्ग संरचना को बनाए रखना चाहता हूं, और साझा लाइब्रेरी का उपयोग करना जारी रखता हूं: मैं से Derived<some type>*
कास्ट सफलतापूर्वक कैसे प्राप्त कर सकता हूं?
इसे कम करने के लिए सुझाव ... 1) पूरी तरह से सुनिश्चित करें कि आपके कंपाइलर को पास किए गए विकल्प आपके प्रोग्राम घटकों के लिए आपके lib घटकों के लिए समान हैं ... वे मनग्रस्त प्रतीकों को प्रभावित कर सकते हैं। 2) '[nm] (http://linux.about.com/library/cmd/blcmdl1_nm.htm)' टूल का उपयोग अपनी लाइब्रेरी ऑब्जेक्ट्स और प्रोग्राम प्रोग्राम दोनों से प्रतीकों को डंप करने के लिए करें ... आपको वही देखना चाहिए आपके लाइब्रेरी घटक (परिभाषित) और आपके टेस्ट कोड (अपरिभाषित) के लिए उलझन वाले प्रतीक – Andrew