क्या C संरचना ऐसा व्यवहार कर सकती है जैसे उसका कोई कार्य था?


13

मैं सी और structएस का उपयोग करता हूं जहां एक संरचना में सदस्य हो सकते हैं लेकिन कार्य नहीं। सादगी के लिए मान लें कि मैं स्ट्रिंग के लिए एक संरचना बनाना चाहता हूं जिसे मैं नाम देता हूं strऔर मैं ऐसा करने में सक्षम होना चाहता हूं str.replace(int i, char c)जहां iस्ट्रिंग का सूचकांक है और cचरित्र को स्थिति में बदलने के लिए चरित्र है i। क्या यह कभी संभव नहीं होगा क्योंकि संरचना में कार्य नहीं हो सकते हैं या फिर भी कुछ तरीका है जिससे हम इस व्यवहार को लागू कर सकते हैं और नकल कर सकते हैं कि एक संरचना में एक (सरल) फ़ंक्शन हो सकता है जो वास्तव में केवल एक नई संरचना के लिए खुद को कॉपी करना है और इसे अपडेट करना है खेतों, जो यह कर सकता है?

तो replaceइस संरचना का तीसरा सदस्य हो सकता है जो एक नई संरचना को इंगित करता है जिसे एक्सेस या इसके समान होने पर अपडेट किया जाता है। क्या यह किया जा सकता है? या वहाँ कुछ बनाया या कुछ सिद्धांत या प्रतिमान है जो मेरे इरादे को रोकता है?

पृष्ठभूमि यह है कि मैं सी कोड लिख रहा हूं और मैं खुद को उन कार्यों को फिर से करना चाहता हूं जिन्हें मैं जानता हूं कि ओओपी भाषाओं में पुस्तकालय निर्मित हैं और ओआरओपी तार और आदेशों में हेरफेर करने का एक अच्छा तरीका होगा।


5
मुझे ईमानदारी से लगता है कि इस तरह की चीज़ों को करने के लिए आपको मुफ्त में लिखने से बेहतर होगा। हालांकि, यदि आपके पास आवश्यक मोक्सी है, तो cs.rit.edu/~ats/books/ooc.pdf
रॉबर्ट हार्वे

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

29
प्रतिस्थापित किया जाता है (और str, i, c) वास्तव में str.replace (i, c) से बहुत खराब है? आपका प्रश्न वास्तव में फ़ंक्शंस को प्रतिस्थापित करने के बारे में नहीं है, यह सी में एक नए वाक्यविन्यास को सूंघने की कोशिश कर रहा है
whatsisname

1
@RobertHarvey cs.rit.edu/~ats/books/ooc.pdf लिंक के लिए धन्यवाद । अच्छी किताब (और कीमत सही है)।
जॉन फोर्कोश

3
@whatsisname: C में, आपको किसी भी तरह से फ़ंक्शन पॉइंटर पॉइंटर को पास करना होगा, इसलिए आप str.replace(&str, i, c)किसी भी तरह समाप्त हो जाएंगे । C ++ thisपॉइंटर के गुजरने को स्वचालित करता है , निश्चित रूप से।
जोनाथन लेफ़लर

जवाबों:


21

आपका कार्य इस तरह दिखना चाहिए।

void
replace(struct string * s, int i, char c);

यह ऑब्जेक्ट को एक पॉइंटर को पहले पैरामीटर के रूप में संचालित करने के लिए स्वीकार करता है। C ++ में, इसे this-pointer के रूप में जाना जाता है और इसे स्पष्ट रूप से घोषित नहीं किया जाना चाहिए। (इसे पाइथन के विपरीत करें जहां इसे करना है।)

अपने फ़ंक्शन को कॉल करने के लिए, आप उस सूचक को स्पष्ट रूप से पास करेंगे। मूल रूप से, आप o.f(…)सिंटैक्स के लिए सिंटैक्स का व्यापार करते हैं f(&o, …)। कोई बड़ी बात नहीं।

यदि आप बहुरूपता (उर्फ virtualफ़ंक्शन) का समर्थन करना चाहते हैं तो कहानी अधिक शामिल हो जाती है । यह सी में भी अनुकरण किया जा सकता है (मैंने इसे इस उत्तर के लिए दिखाया है ।) लेकिन यह हाथ से करना बहुत अच्छा नहीं है।

जैसा कि जान हुडेक ने टिप्पणी की है, आपको फ़ंक्शन नाम के प्रकार (यानी string_replace) के साथ उपसर्ग करने की आदत भी डालनी चाहिए क्योंकि C का कोई नाम-स्थान नहीं है, इसलिए केवल एक ही फ़ंक्शन नाम हो सकता है replace


17
बेशक फ़ंक्शन को शायद बुलाया जाएगा string_replace, क्योंकि सी में फ़ंक्शन ओवरलोडिंग भी नहीं है और आपके पास replaceकुछ अन्य प्रकार के लिए कुछ और होने की संभावना है ...
जन हडेक

2
इसे नाम नहीं दिया जा सकता string_replace। के साथ शुरुआत नाम str, memया wcsएक छोटा अक्षर के बाद भविष्य एक्सटेंशन के लिए आरक्षित हैं।
डेविड कॉनरेड

43

फ़ंक्शन फ़ंक्शन पॉइंटर्स को पकड़ सकते हैं , लेकिन वे वास्तव में केवल वर्चुअल तरीकों के लिए आवश्यक हैं। ऑब्जेक्ट-ओरिएंटेड सी में गैर-आभासी तरीके आमतौर पर एक नियमित फ़ंक्शन के पहले तर्क के रूप में संरचना को पारित करके किया जाता है। पर देखो Gobject एक OOP ढांचे सी के लिए यह मैक्रो का उपयोग करता बॉयलरप्लेट का एक बहुत संभाल करने का एक अच्छा उदाहरण के लिए विरासत और बहुरूपता के लिए आवश्यक।

C को 44 साल पहले बनाया गया था। यह खुले स्रोत के लिए बहुत लोकप्रिय भाषा है। आप यह सोचने वाले पहले व्यक्ति नहीं हैं कि मानक C स्ट्रिंग्स के साथ काम करने के लिए क्लंकी हैं। C स्ट्रिंग पुस्तकालयों के लिए कुछ खोजें। आपको पहिया को सुदृढ़ करने की आवश्यकता नहीं है।


2
अन्य उल्लेखनीय उदाहरण CPython है। कोड कई
ओओपी

@Bakuriu मुझे लगता है कि आप भ्रमित कर रहे हैं Cython और CPython
बिल्ली

1
@ वह शायद पाइथन सी एपीआई का अर्थ है, साइथन
JAB

5
@cat नहीं, CPython स्रोतों को देखें। अधिकांश चीजें वास्तव में OOP प्रतिमान का उपयोग करके की जाती हैं, और वे एक OOP API प्रदान करते हैं जो ज्यादातर python API से मेल खाता है।
बकुरीउ

1
@ बकुरी ओह, आपका मतलब है पायथन का रनटाइम, स्रोत और सी एपीआई नहीं पायथन भाषा। आपकी टिप्पणी ने बहुत स्पष्ट नहीं किया
बिल्ली

8

समारोह संकेत के साथ, आप कर सकते हैं:

str.replace(&str, i, c);

यह आम तौर पर केवल तभी उपयोगी होता है जब कार्यान्वयन बदल सकता है, जिस स्थिति में आपको एक व्यवहार्य उपयोग करना चाहिए, इसलिए ओवरहेड केवल एक पॉइंटर प्रति फ़ीचर है:

str.vtable->replace(&str, i, c);

3
मैं इसे अभी भी string_replace (& str, i, c) के नाम से पुकारता हूँ, फिर string_replace के अंदर vtable का उपयोग करने के बजाय कॉल साइट को vtable के बारे में जानते हैं।
पीट किर्कम

2
@Pete नाम के साथ शुरुआत str(या memया wcs) और एक छोटा अक्षर भविष्य एक्सटेंशन के लिए सी मानक के पास सुरक्षित हैं, तो यह कॉल नहीं करते string_replacestr_replaceठीक है।
डेविड कॉनरेड

3

हाँ, वे कर सकते हैं, की तरह। आप इस तथ्य का उपयोग कर सकते हैं कि सी पॉइंटर्स को मेमोरी, उर्फ ​​फ़ंक्शन पॉइंटर्स में ब्लॉक को कार्य करने की अनुमति देता है और इसका उपयोग करके आप पॉलीमॉर्फिज़्म के साथ-साथ वर्चुअल फ़ंक्शंस (भले ही वह सुंदर नहीं हो) को इंटरफ़ेस बना सकते हैं।

मैंने इस विषय पर एक ब्लॉग पोस्ट लिखी, मेरे एक छात्र के एक प्रश्न के बाद, हाल ही में, C और Go में इंटरफ़ेस-जैसे कोड से संबंधित, आप इसे यहाँ पढ़ सकते हैं:

नॉन-ओओ इंटरफेस पर ब्लॉग पोस्ट

देखें कि क्या यह आपको कोई विचार देता है।

आप बस अपने कोड में एक मुफ्त फ़ंक्शन डाल सकते हैं, और एक "यह" -पॉइंट्टर का उपयोग कर सकते हैं, जिसका अर्थ है कि आप किसी मौजूदा संरचना को काम करने के लिए एक पॉइंटर पास करते हैं, जैसा कि अन्य उत्तरों में वर्णित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.