2017-11-07 31 views
14

मैं सी ++ और डेल्फी के बीच तुलना कर रहा था और मुझे कुछ मुश्किल लगता है।डेल्फी जेनेरिक नेस्टेड क्लासेस

यह बहुत ही आसान सी ++ कोड है:

template<typename T> 
class C { 

class D { 
    T x; 
} 

} 

इस परिदृश्य में, हम उस वर्ग C है यह भी एक टेम्पलेट वर्ग एक टेम्पलेट वर्ग (= सामान्य वर्ग) और नेस्टेड वर्ग D है। यदि Tdouble है, तो के अंदर xdouble है।

मैं यह नहीं कह सकते हैं:

template<typename T> 
class C { 

template<typename T> 
class D { 
    T x; 
} 

} 

एक त्रुटि है कि जब से मैं पहले से ही "अंदर" हूँ C और एक अन्य T एक संघर्ष किया जाएगा। त्रुटि को ठीक करने के लिए, मुझे U जैसे एक अलग नाम का उपयोग करना चाहिए।

template<typename T> 
class C { 

template<typename U> 
class D { 
    T x; 
} 

} 

डेल्फी में, मैं यह लिख सकते हैं:

type 
TClassC<T> = class 
    private 

    type 
    TClassD = class 
    private 
     x: T; 
    end; 

end; 

तो T एक integer है, अब x के बाद से एक integer है (से मैं क्या ऑनलाइन पढ़ने समझ लिया है) TClassDinteger है। डेल्फी में यह भी कानूनी है:

type 
TClassC<T> = class 
    private 

    type 
    TClassD<T> = class // <-- note the <T> repeated!! 
    private 
     x: T; 
    end; 

end; 

अब के बारे में क्या? यदि मैं T को फिर से TClassD में घोषित करने में सक्षम हूं, तो इसका मतलब है कि <T> के बिना मेरे पास एक गैर-जेनेरिक TClassD कक्षा होगी। क्या मैं सही हूँ?

+3

यह जांचने के लिए आपके लिए आसान होना चाहिए, लेकिन मुझे उम्मीद है कि अगर यह कोड संकलित होता है, तो आंतरिक टी बाहरी व्यक्ति को छुपाता है। तो ऐसा लगता है कि आपने अपने आंतरिक प्रकार पैरामीटर के लिए एक अलग नाम इस्तेमाल किया था। 'TClassC 'और फिर' TClassD 'की तरह। –

+0

दूसरे शब्दों में, मेरी उम्मीद यह है कि डेल्फी कोड बिल्कुल आपके सी ++ संस्करण के साथ व्यवहार नहीं करता है, जिसमें कोई क्लैशिंग पैरामीटर नाम नहीं है। लेकिन सी ++ भाषा आपको नाम संघर्ष से बचाती है। –

+0

आपके पहले सी ++ उदाहरण में, 'डी' स्वयं टेम्पलेट क्लास नहीं है,' सी' से टेम्पलेट सिर्फ दायरे में है इसलिए 'डी' इसका उपयोग कर सकता है। आपके दूसरे सी ++ उदाहरण में, 'टी' नामक दो टेम्पलेट पैरामीटर होने पर वास्तव में एक नामकरण संघर्ष है, क्योंकि सी ++ एक ही दायरे में दोहराने वाले पहचानकर्ता पसंद नहीं करता है। डेल्फी जेनेरिक सी ++ टेम्पलेट्स के समान नहीं हैं (भले ही वे समान वाक्यविन्यास का उपयोग करते हैं), और डेल्फी सी ++ की तुलना में इस विशेष उदाहरण में थोड़ा अधिक लचीला है। –

उत्तर

12

इस सरल कार्यक्रम पर विचार करें:

type 
    TClassC<T> = class 
    private 
    type 
    TClassD<T> = class 
    private 
     x: T; 
    end; 
    end; 

var 
    obj: TClassC<Integer>.TClassD<string>; 

begin 
    obj := TClassC<Integer>.TClassD<string>.Create; 
    obj.x := 42; 
end. 

इस कार्यक्रम को संकलित करता है, लेकिन निम्न संकेत उत्सर्जन करता है:

[dcc32 सुझाव]: कंटेनर प्रकार

के प्रकार के मानकों के साथ H2509 पहचानकर्ता 'टी' संघर्ष

असाइनमेंट साबित करता है कि x आंतरिक प्रकार के बजाय बाहरी जेनेरिक पैरामीटर से अपना प्रकार लेता है।

मुझे यह कहना है कि इससे मुझे आश्चर्य हुआ क्योंकि मैं विपरीत की उम्मीद कर रहा था। मैं उम्मीद कर रहा था कि आंतरिक जेनेरिक पैरामीटर बाहरी बाहरी को छुपाएगा। असल में, जहां तक ​​मैं कह सकता हूं, आंतरिक प्रकार के सामान्य पैरामीटर को संदर्भित करने का कोई तरीका नहीं है।

दोनों सामान्य मानकों को संदर्भित करने में सक्षम होने के लिए आपको उनके लिए अलग-अलग नामों का उपयोग करने की आवश्यकता होगी। उदाहरण के लिए:

type 
    TClassC<T1> = class 
    private 
    type 
    TClassD<T2> = class 
    private 
     x: T2; 
    end; 
    end; 

यह वही है जो समान सी ++ टेम्पलेट कोड आपको करने के लिए मजबूर करता है।

मेरे विचार में, यह डेल्फी भाषा की एक डिजाइन कमजोरी है जिसे आपको इस उत्तर के शीर्ष पर कोड संकलित करने की अनुमति है।

+1

जो वास्तव में बहुत अप्रत्याशित है। –

+1

यह आश्चर्यजनक है। यद्यपि यह धारणा को मजबूत करता है कि संकेत और चेतावनियों को आम तौर पर माना जाना चाहिए कि वे त्रुटियां हैं, भले ही कुछ मामलों में संकलक अभी भी पूरा हो जाएगा। –

+3

@ जे ... मुझे संकेत बहुत आश्चर्यजनक लगता है। यदि ऐसा कुछ भी है जो इसके सबसे खतरनाक पहलू है। डेवलपर्स इस मुद्दे के बारे में पर्याप्त रूप से जागरूक हैं क्योंकि संकेत जारी करने के लिए, लेकिन फिर इसे छोड़ दें। वे क्या सोच रहे थे? इसे समझने के बाद तक यह एक मुद्दा था, उन्होंने संकलक को छोड़ने का फैसला किया, जेनेरिक वर्गों को स्वीकार करते हुए जहां सामान्य पैरामीटर का उपयोग नहीं किया जा सकता है? –

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