2010-11-23 16 views
14

में एक संरचना कन्स्ट्रक्टर को ओवरराइड करने के लिए कैसे वर्तमान में फोरट्रान में संरचना कन्स्ट्रक्टर को ओवरराइड करना संभव है? मैं (जैसे फोरट्रान 2003 कल्पना के रूप में) इस तरह का प्रस्ताव उदाहरण देखा है:फोर्टन

module mymod 

    type mytype 
    integer :: x 
    ! Other stuff 
    end type 

    interface mytype 
    module procedure init_mytype 
    end interface 

contains 
    type(mytype) function init_mytype(i) 
    integer, intent(in) :: i 
    if(i > 0) then 
     init_mytype%x = 1 
    else 
     init_mytype%x = 2 
    end if 
    end function 
end 

program test 
    use mymod 
    type(mytype) :: x 
    x = mytype(0) 
end program 

यह मूलतः चर नाम निरर्थक करने के लिए (कारण त्रुटियों का एक ढेर उत्पन्न करता है जैसे त्रुटि: प्रक्रिया विशेषता के साथ 'MyType' संघर्ष के व्युत्पन्न विशेषता 1 पर))। फोर्टन 2003 उदाहरण की एक क्रियात्मक प्रतिलिपि समान त्रुटियों को उत्पन्न करती है। मैंने gfortran 4.4, ifort 10.1 और 11.1 में यह कोशिश की है और वे सभी एक ही त्रुटियां उत्पन्न करते हैं।

मेरा प्रश्न: क्या यह सिर्फ 2003 के किले की एक अनुपूरक विशेषता है? या क्या मैं इसे गलत तरीके से कार्यान्वित कर रहा हूं?

संपादित करें: मैं bug report और announced patch पर इस मुद्दे के बारे में gfortran में आया हूं। हालांकि, मैंने किसी भी भाग्य और समान त्रुटियों के साथ gcc46 के नवंबर निर्माण का उपयोग करने का प्रयास किया है।

संपादित करें 2: उपरोक्त कोड इंटेल फोरट्रान 12.1.0 का उपयोग करके काम करने लगता है।

उत्तर

6

मैंने फोरट्रान 2008 मानक की मेरी प्रतिलिपि से परामर्श लिया। इससे आपको व्युत्पन्न प्रकार के समान नाम के साथ एक सामान्य इंटरफेस को परिभाषित करने की अनुमति मिलती है। मेरा कंपाइलर (इंटेल फोरट्रान 11.1) कोड को संकलित नहीं करेगा हालांकि मुझे संदेह है (2003 मानक के हाथ की एक प्रति के बिना) कि यह फोरट्रान 2003 मानक की एक अभी तक अनुपूरक सुविधा है।

इसके अलावा, आपके प्रोग्राम में एक त्रुटि है। आपका समारोह घोषणा: वैसे भी

type(mytype) function init_mytype(i) 
+0

धन्यवाद, तय। विचलित त्रुटि के लिए माफ़ी, यह एक संक्षिप्त उदाहरण था। –

17

Is it currently possible to override the structure constructor in Fortran?

सं:

type(mytype) function init_mytype 
    integer, intent(in) :: i 

अस्तित्व और एक बहस की मंशा जो समारोह विनिर्देश, जो शायद के रूप में लिखा जाना चाहिए में मौजूद नहीं है निर्दिष्ट करता है यहां तक ​​कि आपके दृष्टिकोण का उपयोग पूरी तरह से कन्स्ट्रक्टर ओवरराइडिंग के बारे में नहीं है। मुख्य कारण यह है कि संरचना कन्स्ट्रक्टर # ओओपी कन्स्ट्रक्टर। कुछ समानता है लेकिन यह सिर्फ एक और विचार है।

आप प्रारंभिक अभिव्यक्ति में अपने गैर-आंतरिक फ़ंक्शन का उपयोग नहीं कर सकते हैं। आप केवल स्थिर, सरणी या संरचना कन्स्ट्रक्टर, आंतरिक कार्यों का उपयोग कर सकते हैं ... अधिक जानकारी के लिए फोरट्रान 2003 ड्राफ्ट में 7.1.7 प्रारंभिक अभिव्यक्ति को देखें।

खाते में है कि तथ्य यह है ले रहा है मैं पूरी तरह से समझ में नहीं आता क्या

type(mytype) :: x 
x = mytype(0) 

और

type(mytype) :: x 
x = init_mytype(0) 

और क्या mymod मॉड्यूल के अंदर इंटरफ़ेस ब्लॉक का उपयोग के पूरे मुद्दे है के बीच वास्तविक अंतर है।

अच्छा, ईमानदारी से बोलना एक अंतर है, विशाल - पहला तरीका भ्रामक है। यह कार्य कन्स्ट्रक्टर नहीं है (क्योंकि फोर्ट्रान में कोई ओओपी कन्स्ट्रक्टर नहीं है), यह एक प्रारंभिक है।

  1. मेमोरी आवंटन:


    मुख्यधारा OOP निर्माता में क्रमिक रूप से दो बातें करने के लिए जिम्मेदार है।

  2. सदस्य प्रारंभिकरण।

आइए अलग-अलग भाषाओं में कक्षाओं को तत्काल करने के कुछ उदाहरण देखें।

में जावा:

MyType mt = new MyType(1); 

एक बहुत ही महत्वपूर्ण तथ्य छिपा हुआ है - वास्तव वस्तु वास्तव में एक वर्ग के प्रकार का एक varibale के लिए सूचक है।

MyType* mt = new MyType(1); 

लेकिन दोनों भाषाओं में एक देख सकते हैं कि दो निर्माता कर्तव्यों भी वाक्य रचना के स्तर पर परिलक्षित होते हैं: सी ++ में बराबर का उपयोग कर ढेर पर आवंटन किया जाएगा। इसमें दो भाग होते हैं: कीवर्ड नया (आवंटन) और कन्स्ट्रक्टर नाम (प्रारंभिकरण)। ऑब्जेक्टिव-सी वाक्य रचना में इस तथ्य को और भी अधिक बल दिया जाता है:

MyType* mt = [[MyType alloc] init:1]; 

कई बार, फिर भी, आप निर्माता मंगलाचरण का एक अन्य स्वरूप देख सकते हैं। ढेर सी पर आवंटन के मामले में ++ विशेष (बहुत खराब) वाक्य रचना निर्माण

MyType mt(1); 

जो वास्तव में ऐसा भ्रामक कि हम सिर्फ इस बात पर विचार नहीं किया जा सकता है का उपयोग करता है।

अजगर

mt = MyType(1) 

दोनों तथ्य वस्तु वास्तव में एक सूचक और तथ्य यह है कि आवंटन ले जगह पहले (सिंटेक्स स्तर पर) छिपे हुए हैं है। और इस विधि को कहा जाता है ... __init__! O_O तो भ्रामक। उस + की तुलना में С ++ स्टैक आवंटन fades। =)


वैसे भी, भाषा में निर्माता करने का विचार एक बयान में आवंटन एक प्रारंभ करने की क्षमता विधि के कुछ विशेष प्रकार का उपयोग कर मतलब। और यदि आपको लगता है कि यह "असली ओओपी" तरीका है तो मेरे पास आपके लिए बुरी खबर है। यहां तक ​​कि Smalltalkdoesn't have constructors। यह कक्षाओं पर new विधि रखने के लिए सिर्फ एक सम्मेलन है (वे मेटा कक्षाओं के सिंगलटन ऑब्जेक्ट्स हैं)। एक ही लक्ष्य प्राप्त करने के लिए Factory Design Pattern कई अन्य भाषाओं में उपयोग किया जाता है।

मैंने कहीं पढ़ा कि फोरट्रान में मॉड्यूल की अवधारणा मॉडुला -2 द्वारा प्रेरित थी। और ऐसा लगता है कि ओओपी विशेषताएं Oberon-2 से प्रेरित हैं। ओबेरॉन -2 में भी कोई रचनाकार नहीं है। लेकिन निश्चित रूप से पूर्व निर्धारित प्रक्रिया के साथ शुद्ध आवंटन नया है (जैसे कि फोरट्रान में एलोक्केट, लेकिन अलोकेट स्टेटमेंट है)। आवंटन के बाद आप (प्रारंभ में होना चाहिए) कुछ प्रारंभकर्ता को कॉल कर सकते हैं, जो कि एक साधारण विधि है। वहां कुछ भी खास नहीं है।

तो आप वस्तुओं को शुरू करने के लिए कुछ प्रकार की फैक्ट्रियों का उपयोग कर सकते हैं। यह वही है जो आपने वास्तव में सिंगलटन ऑब्जेक्ट्स के बजाय मॉड्यूल का उपयोग करके किया था। या यह कहना बेहतर है कि वे (जावा/सी #/... प्रोग्रामर) बाद के कार्यों की कमी के कारण सामान्य कार्यों के बजाय सिंगलटन ऑब्जेक्ट विधियों का उपयोग करते हैं (कोई मॉड्यूल नहीं - सामान्य कार्यों के लिए कोई तरीका नहीं, केवल विधियां)।

इसके अलावा आप इसके बजाय टाइप-बाउंड सब्ब्रूटिन का उपयोग कर सकते हैं।

MODULE mymod 

    TYPE mytype 
    PRIVATE 
    INTEGER :: x 
    CONTAINS 
    PROCEDURE, PASS :: init 
    END TYPE 

CONTAINS 

    SUBROUTINE init(this, i) 
    CLASS(mytype), INTENT(OUT) :: this 
    INTEGER, INTENT(IN) :: i 

    IF(i > 0) THEN 
     this%x = 1 
    ELSE 
     this%x = 2 
    END IF 
    END SUBROUTINE init 

END 

PROGRAM test 

    USE mymod 

    TYPE(mytype) :: x 

    CALL x%init(1) 

END PROGRAM 

init सबरूटीन के this आर्ग के लिए INTENT(OUT) ठीक हो रहा है। क्योंकि हम इस विधि को आवंटन के बाद केवल एक बार और सही कहने की उम्मीद करते हैं। यह नियंत्रित करने के लिए एक अच्छा विचार हो सकता है कि यह धारणा गलत नहीं होगी। कुछ बूलियन ध्वज LOGICAL :: inited से mytype जोड़ने के लिए, यह जांच करें कि यह .false. है और इसे पहले प्रारंभिक पर .true. पर सेट करें, और पुन: प्रारंभ करने के प्रयास पर कुछ और करें। मुझे निश्चित रूप से Google समूह में इसके बारे में कुछ धागा याद है ... मुझे यह नहीं मिल रहा है।

+2

स्पष्टीकरण के लिए धन्यवाद। मैं समझता हूं कि यह शुद्धवादी ओओपी भावना में एक निर्माता नहीं है, और इसी तरह के वैकल्पिक दृष्टिकोण एक ही चीज़ को पूरा करेंगे। इसके बजाय, यह पी 445 (सी .1.6) से एक निकट-वर्बैटिम उदाहरण है, जिसे लेखकों ने एक विशिष्ट कामकाजी ड्राफ्ट में "संरचना कन्स्ट्रक्टर" को कॉल करना चुना है। मुझे आश्चर्य हुआ कि क्या इस तरह के ओवरराइडिंग वर्तमान में फोर्टन के सामान्य कार्यान्वयन में संभव था। लेकिन मैं दिल से आपकी सलाह लेगा, धन्यवाद। –

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