C को 'ऑब्जेक्ट-ओरिएंटेड' भाषा क्यों नहीं माना जाता है?


92

ऐसा लगता है कि सी की अपनी अर्ध-वस्तुएँ हैं जैसे कि 'संरचनाएं' जिन्हें ऑब्जेक्ट के रूप में माना जा सकता है (उच्च-स्तरीय तरीके से जिसे हम सामान्य रूप से सोचते हैं)।

और यह भी, सी फाइलें स्वयं मूल रूप से "मॉड्यूल" अलग हैं, है ना? तब मॉड्यूल 'वस्तुओं' की तरह नहीं हैं? मैं उलझन में हूँ कि C, C C के समान क्यों लगता है, को निम्न-स्तरीय "प्रक्रियात्मक" भाषा माना जाता है, जहाँ C ++ उच्च-स्तरीय "ऑब्जेक्ट-ओरिएंटेड" है

* संपादित करें: (स्पष्टीकरण) क्यों और कहाँ है, एक 'वस्तु' क्या है और क्या नहीं है के लिए रेखा खींची गई है?


40
सभी - क्यों नीचे वोट? यह एक बुनियादी सवाल है लेकिन बुरा नहीं है।
जॉन हॉपकिंस

7
आप O सिद्धांतों का प्रभावी रूप से C में उपयोग कर सकते हैं (और जो लोग आमतौर पर अच्छा C कोड लिखते हैं), लेकिन भाषा को आसान बनाने के आसपास नहीं बनाया गया है, क्योंकि कई और हालिया भाषाएं हैं।
अस्विकौ

5
C के पास एक अलग, सरल, और (ईमानदार होने के लिए) बेहतर परिभाषित (कम से कम खुले स्रोत वाले समुदाय के बीच) डेटा एब्स्ट्रक्शन के लिए दृष्टिकोण है। सी ++ एक अमूर्त बिजलीघर बन जाता है और कई महान चीजों के लिए अनुमति देता है, लेकिन यह समझने की लागत के साथ आता है कि उन्हें कैसे ठीक से उपयोग न करें, जो कि, आम तौर पर आम कार्यक्रमों में काफी गायब है। अधिक जानकारी के लिए मेरा पूरा उत्तर देखें।
यम मार्कोविच

1
शीघ्रता से: संरचना में विधियाँ नहीं हो सकती हैं। (किसी फंक्शन की ओर इशारा करते हुए इसे नहीं काटा जाता)।
एसएफ।

1
सी में ऑब्जेक्ट-आधारित प्रोग्रामिंग करना कुछ कठिनाई के साथ संभव है। लेकिन वह इसे वस्तु उन्मुख नहीं बनाता है ।
वेज

जवाबों:


101

ऐसा लगता है कि C की अपनी अर्ध-वस्तुएँ हैं जैसे 'संरचनाएं' जिन्हें ऑब्जेक्ट माना जा सकता है

आइए एक साथ आप और मैं विकिपीडिया पृष्ठ पर ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के माध्यम से पढ़ते हैं और सी-स्टाइल की उन विशेषताओं की जाँच करते हैं जो पारंपरिक रूप से ऑब्जेक्ट-ओरिएंटेड शैली के अनुरूप हैं।

(OOP) "ऑब्जेक्ट्स" का उपयोग करते हुए एक प्रोग्रामिंग प्रतिमान है - डेटा संरचनाएं जिसमें डेटा फ़ील्ड और विधियों के साथ-साथ उनकी सहभागिता होती है

क्या C संरचनाएं फ़ील्ड और विधियों से मिलकर होती हैं, जो उनकी अंतःक्रियाओं के साथ होती हैं ? नहीं।

प्रोग्रामिंग तकनीकों में डेटा एब्स्ट्रैक्शन, इनकैप्सुलेशन, मैसेजिंग, मोड्युलैरिटी, पॉलीमॉर्फिज़्म और इनहेरिटेंस जैसे फीचर्स शामिल हो सकते हैं।

क्या सी स्ट्रक्चर्स इन चीजों में से कोई एक "प्रथम श्रेणी" में करते हैं? नहीं। भाषा हर तरह से आपके खिलाफ काम करती है।

ऑब्जेक्ट-ओरिएंटेड अप्रोच प्रोग्रामर को डेटा को रखने के लिए प्रोत्साहित करता है जहाँ वह प्रोग्राम के बाकी हिस्सों से सीधे पहुँचा नहीं जा सकता है

क्या सी स्ट्रक्चर्स ऐसा करते हैं? नहीं।

एक ऑब्जेक्ट-ओरिएंटेड प्रोग्राम में आमतौर पर विभिन्न प्रकार की वस्तुएं होंगी, प्रत्येक प्रकार का एक विशेष प्रकार के जटिल डेटा को प्रबंधित किया जा सकता है या शायद एक वास्तविक दुनिया ऑब्जेक्ट या अवधारणा को

क्या सी स्ट्रक्चर्स ऐसा करते हैं? हाँ।

ऑब्जेक्ट्स को उनके डेटा को उचित रूप से उपयोग करने के लिए डिज़ाइन किए गए फ़ंक्शंस के सेट के भीतर अपने डेटा को लपेटने के रूप में सोचा जा सकता है

नहीं।

प्रत्येक ऑब्जेक्ट संदेशों को प्राप्त करने, डेटा को संसाधित करने और अन्य वस्तुओं को संदेश भेजने में सक्षम है

क्या कोई संरचना स्वयं संदेश भेज और प्राप्त कर सकती है? नहीं। क्या यह डेटा को प्रोसेस कर सकता है? नहीं।

OOP डेटा संरचनाएं "अपने स्वयं के ऑपरेटरों को अपने साथ ले जाने" के लिए होती हैं

C में ऐसा होता है? नहीं।

डायनामिक डिस्पैच ... एनकैप्सुलेशन ... सबटाइप पॉलीमॉर्फिज़्म ... ऑब्जेक्ट इनहेरिटेंस ... ओपन रिकर्सन ... ऑब्जेक्ट्स की क्लासेस ... क्लासेस के इंस्टेंस ... मेथड्स जो अटैच्ड ऑब्जेक्ट्स पर काम करते हैं ... मैसेज पासिंग ।। । अमूर्त

सी संरचनाओं के इन सुविधाओं में से कोई हैं? नहीं।

संक्षेप में, आपको लगता है कि संरचना के कौन से लक्षण "वस्तु उन्मुख" हैं? क्योंकि मुझे इस तथ्य के अलावा कोई अन्य नहीं मिल सकता है कि संरचना प्रकार को परिभाषित करती है ।

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

और यह भी, सी फाइलें स्वयं मूल रूप से "मॉड्यूल" अलग हैं, है ना? तब मॉड्यूल 'वस्तुओं' की तरह नहीं हैं?

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

अमूर्तता और एनकैप्सुलेशन बहुत कमजोर हैं। स्पष्ट रूप से मॉड्यूल मॉड्यूलर हैं; इसलिए उन्हें मॉड्यूल कहा जाता है। संदेश? केवल इस अर्थ में कि एक विधि कॉल एक संदेश है और मॉड्यूल में विधियाँ हो सकती हैं। बहुरूपता? नहीं। विरासत? नहीं। मॉड्यूल "वस्तुओं" के लिए बहुत कमजोर उम्मीदवार हैं।


15
मैं असहमत हूं कि "सी ++ का अनुकरण" (आपका कार्यकाल) मुहावरेदार सी नहीं है। एक काउंटर उदाहरण यह होगा कि एक ओएस कर्नेल आमतौर पर फ़ाइल संचालन को कैसे लागू करता है - लिनक्स को एक उदाहरण के रूप में लेते हैं, जहां आपके पास फ़ंक्शन बिंदुओं से भरा संरचना है। वे कुछ हद तक "डोमेन-विशिष्ट" मुहावरे हो सकते हैं (*, निक्स, कहते हैं) पर ड्राइवरों को लिखने के लिए प्रतिबंधित है, लेकिन वे पहचानने योग्य हैं और कुछ उद्देश्यों के लिए काम को काफी सफाई से करते हैं। उपयोगकर्ता मोड लाइब्रेरी के कुछ उदाहरण भी हैं जो OO की कुछ धारणा को अच्छी तरह से करते हैं; Gtk + और पुस्तकालयों पर निर्भर करता है। इसे
हॅसी कहें

5
@asveikau: यह विचार नहीं है कि एक अभ्यास असामान्य है (भले ही अनसुना न हो) और "हैकी" का अर्थ है कि यह, परिभाषा के अनुसार, मुहावरेदार नहीं है?
एडम रॉबिन्सन

19
@ वासविकौ: यकीन है, ऐसी चीजें हैं जो आप सी कार्यक्रमों को स्टाइल में अधिक ओओ बना सकते हैं। लेकिन जैसा कि आप कहते हैं, ऐसा करने के लिए अनुशासन की आवश्यकता होती है; भाषा की विशेषताएँ स्वयं को स्वाभाविक रूप से आपको एनकैप्सुलेशन, बहुरूपता, वर्ग विरासत, और इसी तरह आगे नहीं बढ़ाती हैं। बल्कि, डेवलपर उस पैटर्न को भाषा पर थोप सकता है। इसका मतलब यह नहीं है कि संरचनाएं तार्किक रूप से वस्तुओं के समान हैं। हेक, आप लिस्प में एक ओओ शैली में भी प्रोग्राम कर सकते हैं, लेकिन इसका मतलब यह नहीं है कि कॉन्स सेल ऑब्जेक्ट हैं।
एरिक लिपर्ट

3
@asveikau, क्या मैं सुझाव दे सकता हूं कि आपकी (गलत) व्याख्या "मुहावरे की" के रूप में "स्वयं की" सौम्य है ... मुहावरेदार? :)
बेंजोल

8
@BillK: स्ट्रक्चर्स में C. कोड नहीं हो सकता। स्ट्रक्चर्स में फंक्शन पॉइंटर्स हो सकते हैं , जो डेटा हैं । कार्य बिंदु कोड नहीं हैं । कोड एक प्रोग्रामर द्वारा बनाई गई एक टेक्स्ट आर्टवर्क है।
एरिक लिपर्ट

46

मुख्य शब्द "उन्मुख" है, न कि "वस्तु"। यहां तक ​​कि C ++ कोड जो वस्तुओं का उपयोग करता है, लेकिन उनका उपयोग करता है जैसे संरचनाएं ऑब्जेक्ट ओरिएंटेड नहीं हैं ।

सी और सी ++ दोनों ओओपी कर सकते हैं (सी में कोई एक्सेस कंट्रोल से अलग), लेकिन सी में इसे करने के लिए सिंटैक्स असुविधाजनक (कम से कम कहने के लिए) है, जबकि सी ++ में सिंटैक्स इसे बहुत ही आमंत्रित करता है। C प्रक्रियात्मक के लिए उन्मुख है, जबकि C ++ वस्तुओं के लिए उन्मुख है, उस संबंध में लगभग समान मूल क्षमताओं के बावजूद।

कोड जो वस्तुओं को डिजाइन को लागू करने के लिए उपयोग करता है जो केवल वस्तुओं के साथ किया जा सकता है (आमतौर पर बहुरूपता का लाभ लेने का अर्थ है) वस्तु उन्मुख कोड है। कोड जो ऑब्जेक्ट के थैलों की तुलना में ऑब्जेक्ट के रूप में कम उपयोग करता है, यहां तक ​​कि ऑब्जेक्ट ओरिएंटेड भाषा में इनहेरिटेंस का उपयोग करते हुए, वास्तव में सिर्फ प्रक्रियात्मक कोड है जो कि होने की तुलना में अधिक जटिल है। C में कोड जो फ़ंक्शन पॉइंटर्स का उपयोग करता है जो कि डेटा से भरे हुए पुर्जों के साथ रनटाइम के आसपास बदले जाते हैं, थोड़े बहुरूपता करते हैं, और एक प्रक्रियात्मक रूप से उन्मुख भाषा में भी "ऑब्जेक्ट ओरिएंटेड" कहा जा सकता है।


2
+1 हमारे C को इंगित करने के लिए OO हो सकता है। यह सुविधाजनक नहीं है, लेकिन यह किया जा सकता है।
डायटबुद्ध

यह VBA में ऑब्जेक्ट्स बनाने में आसान है, लेकिन मैं इसे ऑब्जेक्ट 'ओरिएंटेड' नहीं मानता।
जेफ़ओ

VBA मैं "ऑब्जेक्ट आधारित" कहता हूं। यह वस्तुओं का उपयोग करता है, लेकिन बहुरूपिए नहीं, और मैंने इसमें जो थोड़ा सा काम किया है, मुझे यकीन नहीं है कि आप बहुरूपता भी नहीं कर सकते हैं चाहे आप किसी भी प्रकार की कोड कलाकृतियों की कोशिश करें। यह मूल रूप से एन्कैप्सुलेशन के साथ एक प्रक्रियात्मक भाषा है।
काइलबेन

2
अधिकांश भाषाएं OO, कार्यात्मक या भाषा की किसी भी शैली के रूप में कार्य कर सकती हैं। अंतर "ओरिएंटेड" है और मैंने ऐसा पहले कभी नहीं सुना था। काश मैं इसे 3 बार वोट कर सकता और इसे स्वीकार कर सकता, यह सही जवाब है।
बिल के

1
@kylben यह तालिका में SQL कोड को संग्रहीत करने के लिए बहुत अधिक खिंचाव नहीं होगा, तब निकालें और निष्पादित करें (तालिका को अपनी वस्तु बनाते हुए) यह एक दिलचस्प प्रयोग होगा। वास्तव में यह थोड़ा लुभावना है ...
बिल के

19

बहुत उच्चतम स्तर के प्रिंसिपलों पर आधारित:

ऑब्जेक्ट इंटरलिंक तरीके से डेटा और व्यवहार का एक एनकैप्सुलेशन होता है, जैसे कि वे एक पूरे के रूप में काम करते हैं जो कई बार इंस्टेंट हो सकते हैं और यदि आप बाहरी इंटरफ़ेस को जानते हैं तो ब्लैक बॉक्स के रूप में काम करते हैं।

संरचनाओं में डेटा होता है लेकिन कोई व्यवहार नहीं होता है और इसलिए इसे ऑब्जेक्ट नहीं माना जा सकता है।

मॉड्यूल में व्यवहार और डेटा दोनों होते हैं, लेकिन इस तरह से समझाया नहीं जाता है कि दोनों संबंधित हैं और निश्चित रूप से कई बार तत्काल नहीं किया जा सकता है।

और इससे पहले कि आप विरासत और बहुरूपता पर उतरें ...


मॉड्यूल में व्यवहार और डेटा कैसे संबंधित नहीं हैं? मॉड्यूल के अंदर मौजूद डेटा पर मूल रूप से 'व्यवहार' सदस्य कार्य नहीं कर रहे हैं?
डार्क टेम्पलर

4
समस्या यह है कि वे एनकैप्सुलेटेड नहीं हैं, ऐसा नहीं है कि वे संबंधित नहीं हैं।
इयोन कैरोल

वास्तव में वस्तुएं मुख्य रूप से व्यवहार के आसपास केंद्रित होती हैं , डेटा नहीं। डेटा OOP में द्वितीय श्रेणी का नागरिक होना चाहिए। इसके बजाय, संरचनाएं डेटा के आसपास केंद्रित हैं और उनका कोई व्यवहार नहीं है।
स्किलीव्ज

1
@ डार्क टेम्पलर - इयोन ने क्या कहा ... यह रिश्ते की प्रकृति में है। मैं देख सकता हूँ कि आप कहाँ से आ रहे हैं - आप निश्चित रूप से एक मॉड्यूल के भीतर संरचनाओं का उपयोग इस तरह से कर सकते हैं कि यह OO के कुछ बहुत ही मूल तत्वों का अनुकरण करता है, लेकिन आप जो कर रहे हैं उसमें से अधिकांश प्रोग्रामर पर एक सेट से चिपके रहने पर निर्भर करेगा। भाषा को लागू करने के बजाय स्वयं के नियमों को लागू करना। और आप क्यों परेशान होंगे? आपको OO के लाभों में से कोई भी नहीं मिल रहा है - उदाहरण के लिए कोई विरासत नहीं - और आप खुद को प्रतिबंधित कर रहे हैं।
जॉन हॉपकिंस

यह एक सही उत्तर की तुलना में बेहतर उत्तर है।
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

6

"स्ट्रक्चर्स" केवल डेटा हैं। "ऑब्जेक्ट ओरिएंटेशन" का सामान्य त्वरित और गंदा परीक्षण है: "क्या कोई संरचना है जो कोड और डेटा को एक एकल इकाई को एनकैप्सुलेट करने की अनुमति देती है?"। सी विफल रहता है, और इसलिए प्रक्रियात्मक है। C ++ उस परीक्षा को पास करता है।


6
वर्कअराउंड हैं, स्ट्रक्चर्स में स्थिर फ़ंक्शन पॉइंटर्स से लेकर सदस्य फ़ंक्शन हो सकते हैं। उन्हें स्पष्ट thisसूचक की आवश्यकता होगी , लेकिन उस स्थिति में, डेटा और डेटा को संसाधित करने के लिए साधन संरचना के अंदर समझाया जाएगा।
कोडर

@Brian Knoblauch: लेकिन एक सी फ़ाइल ही डेटा और कोड का एक एनकैप्सुलेशन नहीं है ??
डार्क टेम्पलर

@DarkTemplar एक मायने में, हाँ, लेकिन जब तक आप अनुवाद इकाइयाँ बनाने का प्रबंधन नहीं करते, उन्हें संकलित करें और उन्हें रनटाइम में चल रही प्रक्रिया में लोड करें, तो यह आपको थोड़ा अच्छा करता है।

अनुवाद इकाइयाँ? >। <
डार्क टेम्पलर

@Dark टेम्पलर: एक अनुवाद इकाई एक स्रोत फ़ाइल के साथ साथ कुछ भी है #includeउसमें डी, और शून्य से कुछ भी नहीं द्वारा हटा दिया सशर्त शामिल किया जा रहा ( #if, #ifdef, और की तरह)।
डेविड थॉर्नले

5

C, C ++ की तरह, डेटा एब्स्ट्रैक्शन प्रदान करने की क्षमता है , जो ऑब्जेक्ट-ओरिएंटेड-प्रोग्रामिंग प्रतिमान का एक मुहावरा है जो इससे पहले अस्तित्व में था।

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

C ++ में OOP डेटा को सार करने के लिए साधन बढ़ाता है। कुछ लोग कहते हैं कि यह हानिकारक है , जबकि अन्य इसे सही तरीके से उपयोग किए जाने पर एक अच्छा उपकरण मानते हैं।

  • C ++ इस सूचक को तब तक निहित बनाता है जब तक कि उपयोगकर्ता को "कक्षा / संरचना के तरीकों" में पास करने की आवश्यकता न हो, जब तक कि टाइप (कम से कम आंशिक रूप से) पहचाना जा सकता है।
  • C ++ आपको कुछ तरीकों (वर्ग कार्यों) तक पहुंच को प्रतिबंधित करता है, और इसलिए अधिक "रक्षात्मक प्रोग्रामिंग" या "बेवकूफ-प्रूफिंग" की अनुमति देता है।
  • C ++ शुरूआत करके मजबूत प्रकार की सुरक्षा प्रदान करके अमूर्तता को प्रोत्साहित करता है
    1. नई के बजाय ऑपरेटर malloc + डाली
    2. शून्य बिंदुओं के बजाय टेम्पलेट
    3. इनलाइन फ़ंक्शन मैक्रोज़ के बजाय टाइप-वैल्यू प्राप्त कर रहे हैं
    4. पॉलीमॉर्फिज्म में निर्मित जो आपको खुद को लागू करने की आवश्यकता नहीं है, जो आपको अमूर्त पदानुक्रम , अनुबंध और विशेषज्ञता बनाने में मदद करता है ।

हालाँकि, आप पाएंगे कि कई C "हैकर्स" इस बात के लिए उपदेश देते हैं कि कैसे C केवल अमूर्तता की सही मात्रा में पूरी तरह से सक्षम है और C ++ द्वारा बनाया गया ओवरहेड केवल वास्तविक समस्या को हल करने से उन्हें विचलित करता है।

अकुशल अमूर्त प्रोग्रामिंग मॉडल जहां सड़क के दो साल नीचे आप नोटिस करते हैं कि कुछ अमूर्त बहुत कुशल नहीं था, लेकिन अब आपका सभी कोड इसके आस-पास के सभी अच्छे ऑब्जेक्ट मॉडल पर निर्भर करता है, और आप इसे अपने ऐप को फिर से लिखे बिना ठीक नहीं कर सकते। - लिनुस टोरवाल्ड्स

अन्य लोग इसे और अधिक संतुलित तरीके से देखते हैं, नुकसान के साथ दोनों फायदे स्वीकार करते हैं।

सी खुद को पैर में गोली मारना आसान बनाता है; C ++ इसे कठिन बनाता है, लेकिन जब आप इसे करते हैं तो यह आपके पूरे पैर को उड़ा देता है। - ब्रजने स्ट्रॉस्ट्रुप


2

आपको सिक्के के दूसरी तरफ देखने की जरूरत है: C ++।

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

"वास्तविक" वस्तुओं के साथ हमें उदाहरण के लिए सदस्यों को छिपाने की आवश्यकता होती है, या हमारे पास एक वास्तविक के साथ विरासत भी हो सकती है "एक संबंध" और कई और अधिक है।

टिप्पणी के बाद से आगे बढ़ें: खैर यह सही है कि (लगभग) सब कुछ सी के साथ किया जा सकता है (यह हमेशा सच है), लेकिन पहली नज़र में मैंने सोचा कि सी + से अलग सी क्या है जिस तरह से आप किसी प्रोग्राम को डिज़ाइन करते समय सोचते हैं।

केवल एक चीज जो वास्तव में फर्क करती है वह है संकलक द्वारा नीतियों को लागू करना । यानी शुद्ध आभासी कार्य, और ऐसे। लेकिन यह उत्तर केवल तकनीकी मुद्दों से संबंधित होगा, लेकिन मुझे लगता है कि मुख्य अंतर (जैसा कि उल्लेख किया गया है) मूल तरीका है जिसे आप कोड करते समय सोचते हैं, क्योंकि C ++ आपको OOP करने के बजाय ऐसी चीजों को करने के लिए सिंटैक्स में बेहतर तरीके से बनाया गया है। सी में कुछ भद्दा तरीका।


वास्तव में यकीन नहीं है कि "फ़ंक्शन के बंडल" के साथ एक संरचना अवधारणा के लायक क्यों नहीं है? हालांकि उत्तर के लिए +1
डार्क टेम्पलर

1
एक्सेस कंट्रोल (निजी / संरक्षित / सार्वजनिक) के अलावा बाकी सब कुछ स्ट्रक्चर्स के साथ किया जा सकता है।
कोडर

1
@DarkTemplar: ठीक है, आप C में OOP का अनुकरण करने की कोशिश कर सकते हैं (लोग वास्तव में उस विषय पर ईबुक लिख चुके हैं और वास्तविक दुनिया में ऐसा करते हैं, भले ही बहुत कम ही), जैसे कि आप जावा में कार्यात्मक प्रोग्रामिंग का अनुकरण करने का प्रयास कर सकते हैं। लेकिन C इसके लिए शून्य सहायता प्रदान करता है, इसलिए C भाषा ऑब्जेक्ट- ओरिएंटेड नहीं है ।

1

आपने खुद कहा। जबकि C में ऐसी चीजें हैं जो वस्तुओं की तरह हैं, वे अभी भी ऑब्जेक्ट नहीं हैं, और इसीलिए C को OOP भाषा नहीं माना जाता है।


1
ठीक है, मुझे लगता है कि सवाल यह है: क्यों और कहाँ एक वस्तु है और क्या नहीं है के लिए रेखा खींची है?
डार्क टेम्पलर

1

ऑब्जेक्ट ओरिएंटेड एक आर्किटेक्चरल पैटर्न (या यहां तक ​​कि मेटा-पैटर्न) दोनों को संदर्भित करता है, और, इस पैटर्न का उपयोग करके उन भाषाओं को लागू करने या जनादेश देने में मदद करता है।

आप एक "OO" डिज़ाइन लागू कर सकते हैं (Gnome डेस्कटॉप शायद शुद्ध C में किया गया OO का सबसे अच्छा उदाहरण है), मैंने इसे COBOL के साथ भी देखा है!

हालांकि एक OO डिजाइन खुराक को लागू करने में सक्षम होने के कारण भाषा OO नहीं बनती है। शुद्धतावादी यह तर्क देंगे कि जावा और C ++ वास्तव में OO नहीं हैं क्योंकि आप मूल "प्रकार" जैसे "int" और "char" को ओवरराइड या इनहेरिट नहीं कर सकते हैं, और, Java कई उत्तराधिकार का समर्थन नहीं करता है। लेकिन जैसा कि वे सबसे व्यापक रूप से इस्तेमाल की जाने वाली OO भाषाएं हैं और अधिकांश प्रतिमान "अधिकांश" वास्तविक प्रोग्रामर का समर्थन करते हैं, जिन्हें वर्किंग कोड का उत्पादन करने के लिए भुगतान किया जाता है, उन्हें OO भाषा के रूप में माना जाता है।

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


0

आइये जरा OO की परिभाषा पर गौर करें:

  • संदेश
  • encapsulation
  • देर से बांधना

C उन तीनों में से कोई भी प्रदान नहीं करता है। विशेष रूप से, यह मैसेजिंग प्रदान नहीं करता है , जो सबसे महत्वपूर्ण है।


1
मुझे लगता है कि मुझे इससे असहमत होना पड़ेगा। आप निश्चित रूप से सी में मैसेजिंग कर सकते हैं - सी से ऑब्जेक्टिव सी एपीआई के साथ काम करते हैं और आप पाते हैं कि गहराई से - और देर से बाइंडिंग फ़ंक्शन पॉइंटर्स के माध्यम से किया जा सकता है, लेकिन आपको इसे छिपाने के लिए बहुत सारे सिंटैक्टिक चीनी नहीं मिलते हैं। (एनकैप्सुलेशन वास्तव में सी में आसान है; अपूर्ण संरचना के प्रकार; कार्य पूरी तरह से करते हैं।)
डोनल फैलो

OO में वंशानुक्रम को भी महत्वपूर्ण माना जाता है, और C ऐसा नहीं करता है। C में एन्कैप्सुलेशन के लिए निकटतम चीज अलग-अलग फाइलें हैं जिनमें आंतरिक ( static) फ़ंक्शन और डेटा सदस्य हो सकते हैं।
डेविड थॉर्नले

@ डॉनल फेलो, ऑब्जेक्टिव-सी में पास होने वाले वास्तविक संदेश को C99 मैक्रो के रूप में आसानी से लागू किया जा सकता है। केवल एक चीज जो संकलक के लिए जा रही है वह यह है कि यह सभी आवश्यक संरचनाओं को उच्च स्तर के कोड की कुछ पंक्तियों से सांख्यिकीय रूप से उत्पन्न करता है। अधिकांश यदि सभी सुविधाएँ C API से उपलब्ध नहीं हैं।
qpr

0

OO के लिए कई महत्वपूर्ण घटक हैं, लेकिन बड़े हैं कि कोड के अधिकांश को पता नहीं है कि किसी वस्तु के अंदर क्या है (वे सतह इंटरफ़ेस को देखते हैं, कार्यान्वयन नहीं), कि एक वस्तु की स्थिति एक प्रबंधित इकाई है (अर्थात, जब वस्तु का होना बंद हो जाता है, तो उसकी स्थिति होती है), और जब कोई कोड किसी वस्तु पर किसी ऑपरेशन का आह्वान करता है, तो वे ऐसा किए बिना ही यह जान लेते हैं कि ऑपरेशन क्या है या इसमें शामिल है (वे जो भी करते हैं वह एक पैटर्न को फेंकने के लिए है। "संदेश" दीवार पर)।

सी ठीक से एनकैप्सुलेशन करता है; कोड जो एक संरचना की परिभाषा नहीं देखता है (वैध रूप से) उसके अंदर झांकना नहीं कर सकता है। आपको बस एक हेडर फाइल में इस तरह परिभाषा डालना है:

struct FooImpl;
typedef struct FooImpl *Foo;

बेशक, एक फ़ंक्शन की आवश्यकता होगी जो Foos (यानी, एक कारखाना) का निर्माण करता है और जिसे कुछ कार्य आवंटित ऑब्जेक्ट को स्वयं सौंपना चाहिए (यानी, एक "कंस्ट्रक्टर" विधि के माध्यम से), और एक तरीका भी है वस्तु को फिर से निपटाने के दौरान (इसकी "विध्वंसक" विधि से सफाई करते हुए) लेकिन यह विवरण है।

विधि प्रेषण (यानी, मैसेजिंग) भी इस सम्मेलन के माध्यम से किया जा सकता है कि संरचना का पहला तत्व वास्तव में फ़ंक्शन पॉइंटर से भरा संरचना का एक संकेतक है, और यह कि प्रत्येक फ़ंक्शन पॉइंटर्स Fooको इसके पहले तर्क के रूप में लेना होगा । डिस्पैच तब फ़ंक्शन को देखने और सही तर्क के साथ इसे फिर से लिखने के लिए एक मामला बन जाता है, जो कि मैक्रो और थोड़ा चालाक के साथ करना मुश्किल नहीं है । (फ़ंक्शंस की वह तालिका इस बात का मूल है कि C ++ जैसी भाषा में कोई क्लास वास्तव में क्या है।)

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

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


0

मुझे लगता है कि वस्तु-उन्मुख अवधारणाओं को लागू करने के लिए सी पूरी तरह से ठीक और सभ्य है, श्रग । अधिकांश अंतर जैसा कि मैं इसे देखता हूं कि वस्तु-उन्मुख मानी जाने वाली भाषाओं के आम भाजक सबसेट के बीच मेरी तरह के व्यावहारिक दृष्टिकोण से मामूली और वाक्यविन्यास हैं।

आइए, जानकारी छिपाने के साथ शुरू करते हैं। सी में हम एक संरचना की परिभाषा को छिपाकर और अपारदर्शी बिंदुओं के माध्यम से इसके साथ काम करके प्राप्त कर सकते हैं। यह प्रभावी रूप से डेटा फ़ील्ड्स के publicबनाम privateअंतर को मॉडल करता है जैसा कि हम कक्षाओं के साथ प्राप्त करते हैं। और यह करना काफी आसान है और मुश्किल से विरोधी मुहावरे के रूप में, मानक सी लाइब्रेरी जानकारी छुपाने के लिए इस पर बहुत अधिक निर्भर करती है।

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

और हमें एक सिंटैक्स का उपयोग करना होगा, लेकिन इसके fopen(file, ...); fclose(file);विपरीत जो file.open(...); file.close();बड़ा है। असल में किसे परवाह है? हो सकता है कि कोई व्यक्ति जो अपनी आईडीई में ऑटो-पूर्ति पर भारी पड़े। मैं मानता हूं कि यह एक व्यावहारिक दृष्टिकोण से एक बहुत ही उपयोगी विशेषता हो सकती है, लेकिन शायद कोई ऐसा नहीं है जो इस बात पर चर्चा करता है कि क्या कोई भाषा ओओपी के लिए उपयुक्त है।

हमारे पास protectedखेतों को प्रभावी ढंग से लागू करने की क्षमता की कमी है । मैं पूरी तरह वहाँ जमा करूँगा। लेकिन मुझे नहीं लगता कि कोई ठोस नियम है जो कहता है, " सभी ओओ भाषाओं में एक बेस क्लास के सदस्यों तक पहुँचने के लिए उपवर्गों की अनुमति देने की सुविधा होनी चाहिए जो अभी भी सामान्य ग्राहकों द्वारा एक्सेस नहीं की जानी चाहिए ।" इसके अलावा मैं शायद ही कभी संरक्षित सदस्यों के लिए उपयोग के मामले देखता हूं जो रखरखाव बाधा बनने के कम से कम कुछ संदिग्ध नहीं हैं।

और निश्चित रूप से हमें उन अनुरूप vtablesऔर प्रारंभिक को समायोजित करने के लिए थोड़ा और अधिक बॉयलरप्लेट के साथ गतिशील प्रेषण के लिए ओओ बहुरूपता के साथ उन्हें "इंगित" करना है vptrs, लेकिन बॉयलरप्लेट का थोड़ा सा भी मुझे बहुत दुःख नहीं है।

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

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


1
मुझे यकीन नहीं है कि कैसे निर्माणकर्ताओं को ओओपी के लिए एक शर्त नहीं माना जा सकता है। एनकैप्सुलेशन के मूल सार का एक हिस्सा किसी वस्तु के लिए आक्रमणकारियों को सुनिश्चित करने की क्षमता है। और इसके लिए उन अपरिवर्तनीयों के भीतर ऑब्जेक्ट को ठीक से इनिशियलाइज़ करने की आवश्यकता होती है। इसके लिए एक निर्माता की आवश्यकता है: एक या एक से अधिक कार्य, जैसे कि आप यह नहीं कह सकते कि वस्तु अभी तक मौजूद है जब तक कि उनमें से कम से कम एक को नहीं बुलाया गया हो।
निकोल बोलस

जब हमारे पास अपारदर्शी प्रकारों के साथ छुपाने की जानकारी होती है, तो उन्हें त्वरित और कॉपी / क्लोन करने और उन्हें नष्ट करने का एकमात्र तरीका उन हमलावरों को बनाए रखने की क्षमता के साथ निर्माणकर्ता और विनाशकारी के रूप में कार्य करने वाले कार्यों के अनुरूप समतुल्य होता है। यह सिर्फ नहीं सीधे भाषा में मॉडलिंग की है और के रूप सदृश हो सकता है foo_createऔर foo_destroyऔर foo_clone, जैसे

struct Fooऐसे मामले में हम सभी को अपरिवर्तनीय बनाए रखने की आवश्यकता है, यह सुनिश्चित करने के लिए कि इसके डेटा सदस्यों को बाहरी दुनिया द्वारा एक्सेस और म्यूट नहीं किया जा सकता है, जो कि अपारदर्शी प्रकार (घोषित लेकिन बाहरी दुनिया के लिए परिभाषित नहीं हैं) को तुरंत अधिकार देते हैं। यकीनन यह जानकारी को छुपाने का एक मजबूत रूप है, जो कि pimplC ++ में बराबर है।

हां, मुझे पता है कि लोग C में OOP कैसे लागू करते हैं, धन्यवाद। मेरा कहना यह था कि आपके कथन कि कंस्ट्रक्टर "ओओपी के लिए प्रत्यक्ष रूप से एक शर्त नहीं माने जाते हैं" त्रुटि में हैं।
निकोल बोलस

मैं देख रहा हूं, लेमेक सही है कि ... लेकिन उस मामले में हम कह सकते हैं कि सी विनाशकों और निर्माणकर्ताओं के लिए सी (पर्याप्त?) समर्थन प्रदान करता है।

-1

बुरा सवाल नहीं है।

यदि आप किसी OO भाषा को कॉल करने जा रहे हैं, तो आपको सभी प्रक्रियात्मक भाषाओं OO के बारे में भी कॉल करने की आवश्यकता होगी। तो यह शब्द को अर्थहीन बना देगा। c का OO के लिए कोई भाषा समर्थन नहीं है। यदि संरचनाएं हैं, लेकिन संरचनाएं typesकोई वर्ग नहीं हैं।

वास्तव में c में अधिकांश भाषाओं की तुलना में बहुत सारी सुविधाएँ नहीं हैं। यह ज्यादातर के लिए उपयोग है यह गति, सादगी, लोकप्रियता और पुस्तकालयों के टन सहित समर्थन है।

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