2010-09-13 4 views
12

मैं एक स्पष्ट इन्स्टेन्शियशन अनुरोध स्वचालित रूप से भी सभी आधार वर्ग के सदस्यों का दृष्टांत होगा लगा, लेकिन जब इस कोड के निर्माण विजुअल स्टूडियो 2008 या 2010सी ++ कक्षा टेम्पलेट्स के स्पष्ट इंस्टेंटेशंस तत्काल बेस क्लास इंस्टेंट्यूट करें?

ध्यान दें कि foo()bar() अंदर के लिए एक कॉल जोड़ने के लिए संकलक बलों का उपयोग कर मैं एक linker error: unresolved external symbol "public: void Base<int>::foo(int)" मिल तत्काल Base<int>::bar() और निर्माण सफल होता है, इसलिए ऐसा लगता है कि संकलक के पास foo() को तत्काल करने के लिए सभी आवश्यक जानकारी है।

जाहिर है, स्रोत.cpp में स्पष्ट रूप से Base<int> को तत्काल प्रारंभ करने के लिए निर्माण की अनुमति मिलती है, लेकिन जब भी स्पष्ट रूप से व्युत्पन्न कक्षा को तुरंत चालू किया जाता है तो किसी भी निर्भर आधार वर्ग को तुरंत चालू करने की आवश्यकता होती है।

क्या यह सामान्य है? मैं इस मुद्दे के बारे में मानक क्या कहता हूं उसे नहीं मिला।

header.h

template<typename T> 
class Base { 
public: 
    void foo(); 
}; 

template<typename T> 
class Derived : public Base<T> { 
public: 
    void bar(); 
}; 

source.cpp

#include "header.h" 

template<typename T> 
void Base<T>::foo() { } 

template<typename T> 
void Derived<T>::bar() { 
    // this->foo(); // adding this forces instantiation of foo()??? 
} 

template class Derived<int>; 

main.cpp

#include "header.h" 

int main() { 
    Derived<int> d; 
    d.foo(); // Linker Error: unresolved external symbol "public: void Base<int>::foo(int)" 
} 

संपादित करें:

ऐसा लगता है कि मानक कहता है कि केवल कक्षा के सदस्यों को एक स्पष्ट वर्ग तत्कालता द्वारा तत्काल प्राप्त किया जाता है, इसलिए लिंकर त्रुटि मेरे उदाहरण में उचित है।

ध्यान दें कि कक्षा को कक्षा-सिर {सदस्य-विनिर्देशन} द्वारा परिभाषित किया गया है और "कक्षा परिभाषा में सदस्य-विनिर्देश कक्षा के सदस्यों का पूरा सेट घोषित करता है; कोई भी सदस्य कहीं और नहीं जोड़ा जा सकता है।" तो सदस्य केवल घुंघराले ब्रेसिज़ {} के बीच होते हैं, और सार्वजनिक आधार वर्ग के सदस्य व्युत्पन्न वर्ग के सदस्य नहीं बनते हैं, वे व्युत्पन्न वर्ग से या व्युत्पन्न वर्ग की वस्तुओं से ही पहुंच योग्य होते हैं।

मेरा एकमात्र शेष प्रश्न यह है कि मानक निर्दिष्ट करता है कि क्लास टेम्पलेट का स्पष्ट तत्काल केवल सदस्यों को तत्काल करता है, न कि बेस क्लास के सदस्य? मेरा अनुमान है कि यह स्पष्ट रूप से तत्काल तत्काल होने पर अधिक नियंत्रण की अनुमति देता है। कोई भी जो स्पष्ट टेम्पलेट क्लास इंस्टॉलेशन का उपयोग कर रहा है, संभवतः व्युत्पन्न क्लास परिभाषाओं की तुलना में एक अलग फ़ाइल में बेस क्लास परिभाषाओं की संभावना है, और स्पष्ट रूप से प्रत्येक को तुरंत चालू कर देगा।

+0

बेस क्लास के व्युत्पन्न ट्रिगर तत्काल के लिए एक स्पष्ट कन्स्ट्रक्टर जोड़ रहा है? मुझे संदेह है कि संकलक आवश्यकतानुसार अधिक काम न करने की कोशिश कर रहा है। एक कन्स्ट्रक्टर होने से यह महसूस हो सकता है कि इसे बेस बनाने की भी आवश्यकता है, और यह इसे ट्रिगर कर सकता है। इसके अलावा, क्या आपने जीसीसी या अन्य कंपाइलर्स की कोशिश की है? –

+0

किसी तर्क के साथ या बिना किसी कन्स्ट्रक्टर को जोड़ना और बिना "कीवर्ड" के आधार पर या बेस क्लास foo() के तत्कालता को ट्रिगर नहीं करता है, लेकिन व्युत्पन्न सदस्य बार() से foo() को कॉल को निहित तत्कालता को ट्रिगर करता है। – JohnPS

उत्तर

9

The Standard

एक वर्ग टेम्पलेट विशेषज्ञता के स्पष्ट इन्स्टेन्शियशन अपने सदस्यों पहले से स्पष्ट रूप से स्पष्ट इन्स्टेन्शियशन युक्त अनुवाद इकाई में विशेषज्ञता नहीं के सभी इन्स्टेन्शियशन तात्पर्य कहते हैं।

दूसरे शब्दों में, यह अनिवार्य नहीं है कि आधार वर्ग स्पष्ट रूप से तत्काल तत्काल हो जाएं। इससे उन लोगों की निहित तत्कालता होगी जो उनकी सदस्य परिभाषाओं को आगे बढ़ाएंगे।यह मानक में कुछ बदसूरत गड़बड़ है कि क्या कुछ पाठ "सदस्य" का अर्थ है "प्रत्यक्ष" या "विरासत" सदस्य, जैसा कि अक्सर मानक शब्द लिखने वाले व्यक्ति के लिए "स्पष्ट" प्रतीत होता है, लेकिन नहीं जो इसे पढ़ता है। सी ++ 0x ने कुछ स्पष्टीकरण जोड़े हैं (इसमें स्पष्ट तत्काल घोषणाओं और परिभाषा है कि C++ 03 में नहीं है, लेकिन यहां तक ​​कि इसे अनदेखा करने के बीच भी अंतर है, सी ++ 0x वर्डिंग में कुछ और बिट्स हैं अंतर्दृष्टि):

एक स्पष्ट इन्स्टेन्शियशन कि नाम एक वर्ग टेम्पलेट विशेषज्ञता भी अपने सदस्यों (सहित नहीं सदस्यों आधार से कक्षाएं विरासत में मिला है) कि है में से प्रत्येक के एक ही तरह (घोषणा या डी फाई nition) की एक स्पष्ट इन्स्टेन्शियशन है पहले वर्णित अनुसार छोड़कर स्पष्ट तत्कालता वाले अनुवाद इकाई में स्पष्ट रूप से विशिष्ट नहीं किया गया है। [नोट: इसके अतिरिक्त, यह आमतौर पर कक्षा के बारे में कुछ कार्यान्वयन-निर्भर डेटा का एक स्पष्ट तत्काल होगा। - अंत नोट]

+0

+1। क्या उनके पास कोई व्यापक कंबल कथन नहीं है, जैसे कि यह कक्षा और उसके सभी स्थिर सदस्यों की परिभाषा/घोषणा से अलग नहीं है? इसे खोलने से बचें कि क्या vtable को तत्काल किया गया है वह कुरूपता है जिसे वे स्वीकार कर रहे हैं। – Potatoswatter

+1

+1 मानक ने मुझे "क्लास टेम्पलेट विशेषज्ञता" के उपयोग से भ्रमित कर दिया है जिसका अर्थ है "स्पष्ट तत्कालता" बनाम एक इकाई जिसका उपयोग टेम्पलेट <> का उपयोग करके "स्पष्ट विशेषज्ञता" बनाम है। मुझे लगता है कि बेस सदस्यों को तत्काल नहीं करना तुरंत तत्काल हो जाता है और यह कहां जाता है। बेस सदस्यों को व्युत्पन्न वर्ग की तुलना में एक अलग स्रोत फ़ाइल में तत्काल किया जा सकता है। – JohnPS

+0

@Potatoswatter: क्या हमें व्युत्पन्न वर्ग के तत्कालता के दौरान व्युत्पन्न वर्ग के vtable के आकार को निर्धारित करने के लिए केवल बेस क्लास की घोषणा की आवश्यकता नहीं है, और इसके vtable में मान लिंकर द्वारा भरे हुए हैं? अगर किसी भी कॉलिंग फ़ंक्शन को कुछ अनुवाद इकाई में तत्काल नहीं किया जाता है, तो एक लिंकर त्रुटि होगी। – JohnPS

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