आपको C ++ में एक वर्ग बनाम एक संरचना का उपयोग कब करना चाहिए?


949

C ++ में structबनाम a का उपयोग करना किन परिदृश्यों में बेहतर है class?


47
यह केवल C ++ के लिए ही लागू नहीं है, बल्कि ऐसी किसी भी भाषा के लिए है जो संरचना और वर्ग दोनों प्रदान करती है।
जेसन बंटिंग सेप

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

4
मेरा मानना ​​है कि C ++ में स्ट्रक्चर्स का उपयोग करने का कोई गंभीर कारण नहीं है। मेरे लिए संरचनाएं C ++ का एक और निरर्थक "फ़ीचर" हैं जो केवल C के साथ संगतता के लिए मौजूद हैं, जैसे टाइपडिफ। यदि C ++ को शुरू में C के विस्तार के रूप में नहीं माना गया था, और जावा जैसे खरोंच से डिजाइन किया गया था, तो ये मौजूद नहीं होंगे। सामान्य तौर पर, मुझे लगता है कि सी ++ के बारे में कई अजीब चीजों को सी संगतता के साथ करना है।
कोस्टास

5
संरचना - POD (सादे पुराने डेटा) के लिए और सभी सदस्य पहुंच सार्वजनिक है। कक्षा - जब आपको बेहतर एनकैप्सुलेशन की आवश्यकता होती है और कक्षा की स्थिति के साथ काम करने के लिए सदस्य कार्यों की आवश्यकता होती है।
नवनीत केएन

4
यह केवल सम्मेलन द्वारा सच है। डिफ़ॉल्ट एनकैप्सुलेशन के अलावा कोई अंतर नहीं है।
डेव हिलियर

जवाबों:


804

एक के बीच अंतर classहै और एक structC ++ कि structs डिफ़ॉल्ट है publicके सदस्यों और ठिकानों और कक्षाओं डिफ़ॉल्ट है privateके सदस्यों और ठिकानों। दोनों वर्गों और संरचनाओं में और सदस्यों का मिश्रण हो सकता है public, वंशानुक्रम का उपयोग कर सकते हैं और सदस्य कार्य कर सकते हैं।protectedprivate

मैं किसी भी वर्ग जैसी सुविधाओं के बिना सादे-पुराने-डेटा संरचनाओं के रूप में संरचनाओं का उपयोग करने की सिफारिश करूंगा, और कक्षाओं को privateडेटा और सदस्य कार्यों के साथ समग्र डेटा संरचनाओं के रूप में उपयोग कर सकता हूं ।


99
बिना मॉडिफ़ायर या विधियों वाली संरचना को POD संरचना कहा जाता है, जो C पुस्तकालयों के साथ एक बैकवर्ड संगत इंटरफ़ेस के रूप में मौजूद है क्योंकि यह (माना जाता है) कि इसे C संरचना कहा जाता है। हालांकि इसके अलावा एक अपवाद, केवल अंतर के रूप में कहा गया है।
वर्कमाड 3

26
@ workmad3: नाम भ्रामक है, लेकिन 9/4 (C ++ 03) कहता है: "एक POD- संरचना एक समग्र वर्ग है, जिसमें गैर-POD- संरचना, गैर-POD- संघ का कोई गैर-स्थैतिक डेटा सदस्य नहीं होता है (या ऐसे प्रकारों की सरणी) या संदर्भ, और इसमें कोई उपयोगकर्ता-निर्धारित प्रतिलिपि असाइनमेंट ऑपरेटर और कोई उपयोगकर्ता-निर्धारित विध्वंसक नहीं है। " "संरचना" वर्ग-कुंजी का उपयोग करने पर कोई प्रतिबंध नहीं है और "सार्वजनिक" का उपयोग करने पर प्रतिबंध नहीं है (कुल आवश्यकताओं के लिए 8.5.1 / 1 देखें)। यह "संरचना" और "वर्ग" के बीच अंतर नहीं है।

5
"एग्रीगेट" के आपके उपयोग को गलत समझा जा सकता है, मानक की परिभाषा को देखते हुए। :)

3
स्ट्रॉस्ट्रप की "सिद्धांतों और अभ्यास" पुस्तक के अनुसार: "उन प्राथमिकताओं का मुख्य रूप से उपयोग किया जाना चाहिए जहां सदस्य किसी भी मूल्य ले सकते हैं" (यानी जहां कोई सार्थक वर्ग अपरिवर्तनीय परिभाषित नहीं किया जा सकता है)
एंटीबॉडी 13

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

229

जैसा कि बाकी सभी नोट करते हैं कि वास्तव में केवल दो वास्तविक भाषा अंतर हैं:

  • structसार्वजनिक उपयोग के classलिए चूक और निजी उपयोग के लिए चूक।
  • जब इनहेरिट, structडिफ़ॉल्ट रूप में publicविरासत और classकरने के लिए डिफ़ॉल्ट privateविरासत। (विडंबना यह है कि C ++ में बहुत सी चीजों के साथ, डिफ़ॉल्ट पीछे की ओर है: publicवंशानुक्रम अभी तक अधिक सामान्य विकल्प है, लेकिन लोग शायद ही कभी struct" public" कीवर्ड टाइप करने से बचाने के लिए घोषणा करते हैं ।

लेकिन व्यवहार में वास्तविक अंतर एक class/ के बीच है structकि एक निर्माता / विध्वंसक और एक है कि घोषित नहीं करता है। "सादे-पुराने-डेटा" पीओडी प्रकार के लिए कुछ गारंटीएं हैं, जो कि क्लास के निर्माण से पहले एक बार लागू होने पर लागू नहीं होती हैं। इस भेद को स्पष्ट रखने के लिए, बहुत से लोग जानबूझकर केवल structPOD प्रकारों के लिए s का उपयोग करते हैं, और, यदि वे किसी भी तरीके को जोड़ने जा रहे हैं, तो उपयोग करें class। नीचे दो टुकड़ों के बीच का अंतर अन्यथा अर्थहीन है:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(संयोग से, यहाँ "POD प्रकार" के बारे में कुछ अच्छी व्याख्याओं के साथ एक सूत्र है: वास्तव में C ++ में POD क्या हैं? )


विरासत के अंतर के बारे में अच्छा उदाहरण: यहाँ
लीरन ओरवी

8
चाहे आप का उपयोग करें structया इस बात classका कोई असर न हो कि आपकी वस्तु POD है या नहीं और आपको कॉपी कंस्ट्रक्टर / डिस्ट्रक्टर को परिभाषित करना चाहिए या नहीं। सदस्य कार्यों का POD होने का भी कोई असर नहीं होता है। जैसा कि मैंने लिखा है कि आपने जो लिखा है, मैं देख रहा हूं कि आप अन्यथा सुझाव नहीं दे रहे हैं, लेकिन वर्तमान शब्द भ्रमित कर रहा है
डेविड स्टोन

1
@DavidStone मूल रूप से, POD स्ट्रक्चर्स को C कोड के साथ बैकवर्ड-संगत होने की गारंटी दी जाती है, और इस प्रकार मूल रूप से इन्हें C- स्टाइल स्ट्रक्चर्स के रूप में डिज़ाइन किया जाना चाहिए।
जस्टिन टाइम - मोनिका

3
इस उत्तर का "वास्तविक अंतर" हिस्सा पूरी तरह से गलत है।
जुआनकोपनज़ा

177

मौजूदा उत्तरों में बहुत सी गलतफहमियाँ हैं।

दोनों classऔर structएक वर्ग घोषित करते हैं।

हां, आपको कक्षा की परिभाषा के अंदर अपने पहुँच को संशोधित करने वाले खोजशब्दों को पुनर्व्यवस्थित करना पड़ सकता है, इस पर निर्भर करता है कि आपने किस कक्षा को घोषित किया था।

लेकिन, सिंटैक्स से परे, एक दूसरे को चुनने का एकमात्र कारण सम्मेलन / शैली / वरीयता है।

कुछ लोग structसदस्य कार्यों के बिना कक्षाओं के लिए कीवर्ड के साथ रहना पसंद करते हैं, क्योंकि परिणामस्वरूप परिभाषा "सी से एक सरल संरचना" की तरह दिखती है।

इसी तरह, कुछ लोग classसदस्य कार्यों और privateडेटा के साथ कक्षाओं के लिए कीवर्ड का उपयोग करना पसंद करते हैं , क्योंकि यह उस पर "वर्ग" कहता है और इसलिए ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग पर उनकी पसंदीदा पुस्तक से उदाहरण दिखता है।

वास्तविकता यह है कि यह पूरी तरह से आपके और आपकी टीम के लिए है, और यह आपके कार्यक्रम के लिए वास्तव में कोई फर्क नहीं पड़ेगा।

निम्नलिखित दो वर्ग उनके नाम को छोड़कर हर तरह से बिल्कुल समान हैं:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Redeclaring करते समय आप कीवर्ड भी स्विच कर सकते हैं:

class Foo;
struct Bar;

(हालांकि यह विज़ुअल स्टूडियो गैर-अनुरूपता के कारण बनाता है , ताकि कंपाइलर ऐसा करने पर आपको चेतावनी दे।)

और निम्नलिखित अभिव्यक्तियाँ सत्य का मूल्यांकन करती हैं:

std::is_class<Foo>::value
std::is_class<Bar>::value

हालाँकि, ध्यान दें कि आप कीवर्ड्स को पुनर्परिभाषित करते समय स्विच नहीं कर सकते हैं ; यह केवल इसलिए है क्योंकि अनुवाद इकाइयों में (एक-परिभाषा नियम के अनुसार) डुप्लिकेट क्लास की परिभाषाएँ "टोकन के समान अनुक्रम से मिलकर" होनी चाहिए । इसका मतलब है आप भी नहीं भेज सकते const int member;के साथ int const member;, और के शब्दों के साथ कोई संबंध नहीं है classया struct


15
यह बहुत जानकारीपूर्ण था, और ईमानदारी से मेरा पसंदीदा जवाब था। हर कोई उन्हें अलग-अलग संस्थाओं के रूप में मान रहा है, जब हुड के नीचे, वे समान हैं। मुझे आश्चर्य है कि अगर Arduino वातावरण में एक संरचनात्मक परिभाषा को cpp वर्ग माना जाता है, तो यह देखते हुए कि इसे g ++ का उपयोग करके संकलित किया गया है।
बेंजामिन

4
@ बेशक यह है। Arduino संकलक C ++ को संकलित करता है; इसका अंत है।
अंडरस्कोर_ड

6
इसलिए अगर मैं इसे सही समझ रहा हूं: जब तक आपके दृश्यता संशोधक स्पष्ट नहीं होते हैं, तब तक छोड़ा नहीं जाता, इससे कोई फर्क नहीं पड़ता। आप कुछ भी नहीं बल्कि स्ट्रक्चर्स का उपयोग करके एक विशाल C ++ एप्लिकेशन लिख सकते हैं; या आप संरचना के हर मामले को कक्षा में बदल सकते हैं। जब तक आप डिफ़ॉल्ट दृश्यता का उपयोग नहीं कर रहे हैं, तब तक एप्लिकेशन ठीक उसी तरह होंगे।
रयान लुंडी

मुझे यकीन नहीं है कि C ++ प्रोग्राम की एक अनुवाद इकाई में पूरी घोषणा class foo { public: ... };हो सकती है और दूसरा ऐसा हो सकता है struct foo { ... };जिसे "बिल्कुल समकक्ष" दावे के अनुसार सही रखना होगा। यह इस कारण से आता है कि अपूर्ण घोषणाएँ struct foo;और class foo;विनिमेय हैं। ये वर्ग निकाय को निर्दिष्ट नहीं करते हैं, और इसलिए वे एक्सेस लेआउट के लिए कुछ भी नहीं बोलते हैं।
कज़

@ काज: आप सही कह रहे हैं - यदि परिभाषाएं वस्तुतः एक ही प्रकार की हैं, तो उन्हें व्यवहार को अच्छी तरह से परिभाषित करने के लिए शाब्दिक रूप से समान होना चाहिए। Struct कुंजी और वर्ग-कुंजी अन्यथा तार्किक विनिमय यद्यपि (जहां अर्थ विज्ञान प्रभावित नहीं हैं), और Fooऔर Barअभी भी बराबर / समान प्रकार के होते हैं। मैंने "जब redeclaring " कहना सुनिश्चित किया और एक उदाहरण दिया। यह सोचने के लिए आइए, मैं यह स्पष्ट करने के उत्तर में यह स्पष्ट कर दूंगा कि मैं यूबी में लोगों को गुमराह नहीं कर रहा हूं
हल्की फुल्की दौड़ कक्षा

54

क्लास के बजाय एक ही समय मैं एक संरचना का उपयोग करता हूं, जब फ़ंक्शन कॉल में उपयोग करने से पहले एक फ़ंक्टर को सही घोषित किया जाता है और स्पष्टता के लिए सिंटैक्स को कम करना चाहता है। उदाहरण के लिए:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 

35
अब जब यह कई साल बाद है और C ++ 11 को सभी प्रमुख कंपाइलरों द्वारा समर्थित किया गया है, तो लैंबडा इसे और भी संक्षिप्त बना देता है

36

से सी ++ पूछे जाने वाले प्रश्न लाइट :

किसी संरचना के सदस्य और आधार वर्ग डिफ़ॉल्ट रूप से सार्वजनिक होते हैं, जबकि कक्षा में वे निजी रूप से डिफ़ॉल्ट होते हैं। ध्यान दें: आपको अपने आधार वर्गों को स्पष्ट रूप से सार्वजनिक, निजी या संरक्षित करना चाहिए, बजाय कि चूक पर भरोसा करने के।

संरचना और वर्ग अन्यथा कार्यात्मक रूप से समतुल्य हैं।

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


1
मुझे समझ में नहीं आता कि वे यह क्यों कह रहे हैं कि संरचना और वर्ग कार्यात्मक रूप से समान हैं, लेकिन कुछ मामलों में बिना किसी तर्क के एक से दूसरे को पसंद करने के लिए कह रहे हैं ..
deetz

3
इसका कारण है सम्मेलन। कंपाइलर परवाह नहीं करता है कि आप किसका उपयोग करते हैं, लेकिन आपके कोड को देखने वाले एक अन्य डेवलपर को आपके समझने का एक आसान समय होगा।
ताल प्रेसमैन

3
@deetz: पूरा तीसरा पैराग्राफ तर्कपूर्ण है।
ऑर्बिट में

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

21

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

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

जाहिर है, यह वही चीज है जो आप सी में करेंगे, लेकिन मुझे लगता है कि संदेश को एक कक्षा में डिकोड करने का ओवरहेड आमतौर पर इसके लायक नहीं है।


वही सी। में प्राप्त किया जा सकता है
यूजीन बुजक

11
या आप केवल फ़ंक्शन operator >>लिखने के बजाय एक वर्ग पर लागू कर सकते हैं processMessage, जो आपके C ++ को उचित C ++ की तरह अधिक और सी की तरह कम दिखाई देगा
Nick Bastin

1
इस तथ्य के अलावा कि यह विभिन्न प्रणालियों के बीच पोर्टेबल नहीं है, यह अलियासिंग नियमों का उल्लंघन करता है, इसलिए यह एक एकल वास्तुकला के भीतर भी काम करने की गारंटी नहीं है।
अंडरस्कोर_ड

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

1
@ सटवा हुह, अच्छी बात है। अलियासिंग यहाँ एक समस्या नहीं होगी क्योंकि पॉइंटर्स में से एक एक charप्रकार है, जिसे अलियासिंग से छूट मिलती है। हालांकि, अभी भी एक समस्या है, एक अलग से एक: char*एक अलग प्रकार के लिए कास्टिंग , अगर वास्तव में उस पते पर पहले से ही आरंभिक प्रकार का कोई भी ऑब्जेक्ट नहीं था, तो यूबी है क्योंकि यह जीवन भर के नियमों का उल्लंघन करता है। Afaik, भले ही गंतव्य प्रकार तुच्छ रूप से रचनात्मक है, बस आवंटित स्मृति C ++ के लिए औपचारिक रूप से उस स्मृति को उस प्रकार के रूप में व्यवहार करने की अनुमति देने के लिए पर्याप्त नहीं है।
अंडरस्कोर_ड

19

आप C ++ में "स्ट्रक्चर" का उपयोग कर सकते हैं यदि आप एक लाइब्रेरी लिख रहे हैं जिसका इंटर्नल C ++ है लेकिन एपीआई को C या C ++ कोड से भी कॉल किया जा सकता है। आप बस एक ही हेडर बनाते हैं जिसमें स्ट्रक्चर्स और ग्लोबल एपीआई फ़ंक्शंस होते हैं जिन्हें आप C और C ++ कोड दोनों के साथ एक्सपोज़ करते हैं:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

तब आप C ++ कोड का उपयोग करके C ++ फ़ाइल में फ़ंक्शन बार () लिख सकते हैं और इसे C से कॉल करने योग्य बना सकते हैं और दोनों दुनिया घोषित किए गए संरचना के माध्यम से डेटा साझा कर सकते हैं। C और C ++ को मिलाते समय पाठ्यक्रम के अन्य विवरण हैं लेकिन यह एक सरल उदाहरण है।


2
सबसे अच्छा फिटिंग जवाब। सी-अनुकूलता वास्तव में सबसे महत्वपूर्ण कारण है। डिफ़ॉल्ट एक्सेस जैसी अन्य सभी सामग्री गूढ़ है।
वैलेंटाइन हेनिट्ज

16

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

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};

1
+1 कुछ सदस्य कार्यों के साथ एक संरचना का एक उदाहरण देने के लिए जो आपको ऐसा नहीं लगता है कि आपने "संरचना को हटा दिया है"।
einpoklum

9

मेरे अपने प्रश्न का जवाब देने के लिए (बेशर्मी से), जैसा कि पहले ही उल्लेख किया गया है, सी ++ में उनके लिए एक्सेस विशेषाधिकारों में एकमात्र अंतर है।

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


9

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

यदि यह आपके लिए चिंता का विषय नहीं है, तो मुझे लगता है कि "क्लास" के बजाय "संरचना" का उपयोग इरादे का एक अच्छा संचारक है (जैसा कि @ZeroSignal ने ऊपर कहा है)। संरचनाओं में अधिक पूर्वानुमानित नकल करने वाले शब्दार्थ भी होते हैं, इसलिए वे डेटा के लिए उपयोगी होते हैं जिन्हें आप बाहरी मीडिया में लिखना चाहते हैं या तार पर भेज सकते हैं।

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

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

... लेकिन यह वास्तव में केवल संरचना के डिफ़ॉल्ट सुरक्षा स्तर का सार्वजनिक होने का लाभ उठा रहा है ...


1
यह POD का सही उपयोग नहीं है। एक संरचना (या वर्ग) POD संरचना हो सकती है यदि (और केवल यदि) तो इसमें केवल POD सदस्य होते हैं।
मार्टिन यॉर्क

4
"भविष्य कहनेवाला नकल शब्दार्थ": सहानुभूति वर्ग के लिए समान है (और एक ही समस्या है (उथले प्रतिलिपि))।
मार्टिन यॉर्क

2
यह पोस्ट आपको विश्वास होगा (उम्मीद से दुर्घटना से) कि सभी संरचनाएं PODs हैं। यह बिल्कुल सच नहीं है। मैं उम्मीद करता हूं कि लोग इससे गुमराह न हों।
माइकल डोरस्ट

8

C ++ के लिए, वास्तव में स्ट्रक्चर्स और क्लासेस में बहुत अंतर नहीं है। मुख्य कार्यात्मक अंतर यह है कि एक संरचना के सदस्य डिफ़ॉल्ट रूप से सार्वजनिक होते हैं, जबकि वे कक्षाओं में डिफ़ॉल्ट रूप से निजी होते हैं। अन्यथा, जहां तक ​​भाषा का सवाल है, वे समकक्ष हैं।

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


4

वे बहुत ज्यादा एक ही बात कर रहे हैं। C ++ के जादू के लिए धन्यवाद, एक संरचना फ़ंक्शंस को पकड़ सकती है, वंशानुक्रम का उपयोग कर सकती है, "नया" और इसी तरह एक वर्ग का उपयोग करके बनाया जा सकता है

एकमात्र कार्यात्मक अंतर यह है कि एक वर्ग निजी पहुंच अधिकारों से शुरू होता है, जबकि एक संरचना सार्वजनिक रूप से शुरू होती है। यह C के साथ पीछे की संगतता है।

व्यवहार में, मैंने हमेशा डेटा धारकों और कक्षाओं को ऑब्जेक्ट के रूप में उपयोग किया है।


4

जैसा कि दूसरों ने बताया है

  • दोनों डिफ़ॉल्ट दृश्यता के अलावा बराबर हैं
  • किसी भी कारण से एक या दूसरे का उपयोग करने के लिए मजबूर होने के कारण हो सकते हैं

स्ट्रॉस्ट्रुप / सटर से कौन सा उपयोग करना है, इसके बारे में एक स्पष्ट सिफारिश है:

वर्ग का उपयोग करें यदि वर्ग में एक आक्रमणकारी है; यदि डेटा सदस्य स्वतंत्र रूप से भिन्न हो सकते हैं तो संरचना का उपयोग करें

हालांकि, ध्यान रखें कि घोषित sth को अग्रेषित करना बुद्धिमानी नहीं है। एक वर्ग के रूप में ( class X;) और इसे संरचना के रूप में परिभाषित करें ( struct X { ... })। यह कुछ लिंकर्स (जैसे, जी ++) पर काम कर सकता है और दूसरों पर असफल हो सकता है (जैसे, एमएसवीसी), इसलिए आप खुद को डेवलपर नरक में पाएंगे।


क्या आप इन लिंकर समस्याओं का वर्णन कर सकते हैं?
को ऑर्बिट में

@LightnessRacesinOrbit मैं दुर्भाग्य से नहीं कर सकता। मैं एक उदाहरण भी नहीं दे पा रहा हूं। तुच्छ class Foo; struct Foo { void bar() {} }; int main() { Foo().bar(); }न केवल MSVC 2017 के साथ संकलित करता है और चलाता है, यह एक स्पष्ट चेतावनी भी उत्पन्न करता है Fooजिसे घोषित किया गया था structलेकिन जैसा कि परिभाषित किया गया है class। लेकिन मुझे यह भी स्पष्ट रूप से याद है कि उस बेवकूफ़ बग को खोजने में हमारी टीम को आधे दिन का समय लगा। मुझे यकीन नहीं है कि हमने जो MSVC वर्जन वापस इस्तेमाल किया है।
पसिबी

लिंकर को इस बारे में भी नहीं पता होना चाहिए कि आपने उपयोग किया था classया structआगे की घोषणा पर, और दोनों मानक के अनुसार स्वतंत्र रूप से विनिमेय हैं (हालांकि यह ज्ञात है कि वीएस चेतावनी देते हैं; मैंने हमेशा माना कि यह केवल स्पष्ट प्रोग्रामर गलतियों से बचने के लिए था)। कुछ यहाँ गंध नहीं है। क्या आप सुनिश्चित हैं कि यह ODR उल्लंघन बग नहीं था?
को ऑर्बिट में


मुझे ठीक से याद नहीं है। समस्या सीधे एक आवेदन में नहीं हुई थी, लेकिन एक पुस्तकालय में जिसका उपयोग एक gtest में किया गया था। मुझे सिर्फ इतना पता है कि लिंकर ने असंगत त्रुटियों (LNK ???) का उत्पादन किया था। एक बार जब मैं struct-forward की जगह class, समस्याओं दूर चला गया। आज के रूप में, मुझे यह बहुत अजीब लगता है। मुझे खुशी होगी अगर आप इस पर कुछ प्रकाश डाल सकते हैं।
पसिबी

3

कक्षा।

कक्षा के सदस्य डिफ़ॉल्ट रूप से निजी हैं।

class test_one {
    int main_one();
};

के बराबर है

class test_one {
  private:
    int main_one();
};

तो अगर तुम कोशिश करो

int two = one.main_one();

हमें एक त्रुटि मिलेगी: main_one is privateक्योंकि इसकी पहुंच सुलभ नहीं है। हम इसे एक सार्वजनिक यानी निर्दिष्ट करके इसे आरंभ कर सकते हैं

class test_one {
  public:
    int main_one();
};

Struct।

एक संरचना एक ऐसा वर्ग है जहां सदस्य डिफ़ॉल्ट रूप से सार्वजनिक होते हैं।

struct test_one {
    int main_one;
};

मतलब main_oneनिजी है

class test_one {
  public:
    int main_one;
};

मैं डेटा स्ट्रक्चर्स के लिए स्ट्रक्चर्स का उपयोग करता हूं, जहां सदस्य कोई भी मूल्य ले सकते हैं, यह आसान है।


3

structओवर classका एक फायदा यह है कि यह कोड की एक पंक्ति को बचाता है, यदि "पहले सार्वजनिक सदस्यों, फिर निजी" का पालन किया जाता है। इस प्रकाश में, मुझे कीवर्ड classबेकार लगता है ।

यहाँ केवल structऔर कभी नहीं का उपयोग करने का एक और कारण है class। C ++ के लिए कुछ कोड शैली दिशानिर्देश फ़ंक्शन मैक्रोज़ के लिए छोटे अक्षरों का उपयोग करने का सुझाव देते हैं, औचित्य यह है कि जब मैक्रो को इनलाइन फ़ंक्शन में परिवर्तित किया जाता है, तो नाम को बदलने की आवश्यकता नहीं होनी चाहिए। मुझे भी। आपके पास आपकी अच्छी सी-शैली की संरचना है और एक दिन, आपको पता चलता है कि आपको एक कंस्ट्रक्टर, या कुछ सुविधा विधि जोड़ने की आवश्यकता है। क्या आप इसे ए में बदलते हैं class? हर जगह?

structS और classes के बीच भेद करना बहुत अधिक परेशानी है, हम जो कर रहे हैं वह करने के तरीके में हो जाना - प्रोग्रामिंग। C ++ की बहुत सी समस्याओं की तरह, यह पीछे की संगतता के लिए मजबूत इच्छा से उत्पन्न होती है।


आपको इसे एक में बदलने की आवश्यकता क्यों होगी class? क्या आपको लगता है कि structकीवर्ड से परिभाषित एक वर्ग में सदस्य कार्य या एक निर्माता नहीं हो सकता है?
ऑर्बिट में

@LightnessRacesinOrbit के कारण 1. स्थिरता और 2. कुछ स्थैतिक विश्लेषक 1. के उल्लंघन के बारे में शिकायत करते हैं
Vorac

यह पालन नहीं करता है। आप किस अन्य "निरंतरता" का पालन करते हैं? सदस्य के साथ हर वर्ग joe()को classकीवर्ड के साथ परिभाषित किया जाना चाहिए ? कम से कम 4 intसदस्यों वाले प्रत्येक वर्ग को structकीवर्ड के साथ परिभाषित किया जाना चाहिए ?
हल्बी की

@LightnessRacesinOrbit मैं मुहावरे की बात कर रहा हूँ "POD समुच्चय को परिभाषित किया गया है struct, विधियों के साथ समुच्चय को परिभाषित किया गया है class"। बहुत झंझट।
वोरैक

2

वे अलग-अलग चूक के साथ एक ही बात कर रहे हैं (डिफ़ॉल्ट रूप से निजी class, और सार्वजनिक रूप से डिफ़ॉल्ट रूप से struct), इसलिए सिद्धांत रूप में वे पूरी तरह से विनिमेय हैं।

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


2

डिफ़ॉल्ट रूप से संरचना में सार्वजनिक पहुंच है और डिफ़ॉल्ट रूप से कक्षाओं में निजी पहुंच है।

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


2

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

हालाँकि दोनों के बीच एक बड़ा अंतर यह है कि structचूंकि C में एक कीवर्ड समर्थित है जबकि classऐसा नहीं है। इसका मतलब है कि एक एक का उपयोग कर सकते structएक में फ़ाइल है कि हो सकता है शामिल हैं #includeइतने लंबे समय के रूप में या तो सी ++ या सी में structएक सादे सी शैली है structऔर में सब कुछ शामिल फ़ाइल सी के साथ संगत है, यानी कोई सी ++ जैसे विशिष्ट खोजशब्दों private, public, कोई तरीके, कोई विरासत, आदि आदि।

एसी शैली structका उपयोग अन्य इंटरफेस के साथ किया जा सकता है जो इंटरफ़ेस पर structडेटा को आगे और पीछे ले जाने के लिए सी शैली का उपयोग करते हैं ।

एसी शैली structएक प्रकार का टेम्पलेट है (सी ++ टेम्पलेट नहीं है, बल्कि एक पैटर्न या स्टैंसिल है) जो मेमोरी क्षेत्र के लेआउट का वर्णन करता है। इन वर्षों में C से प्रयोग करने योग्य और C प्लग-इन (यहाँ जावा और पायथन और विज़ुअल बेसिक को देखकर) के साथ प्रयोग करने योग्य है, जिनमें से कुछ सी शैली के साथ काम करते हैं struct


1

तकनीकी रूप से दोनों C ++ में समान हैं - उदाहरण के लिए एक संरचना के लिए अतिभारित ऑपरेटरों आदि के लिए संभव है।

तथापि :

जब मैं एक "कार्यात्मक" ऑब्जेक्ट के साथ काम कर रहा होता हूं तो मैं एक साथ कई प्रकार की जानकारी पास करना चाहता हूं, जब मैं कई प्रकार की जानकारी पास करना चाहता हूं, तो मैं संरचना का उपयोग करता हूं।

आशा है ये मदद करेगा।

#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

उदाहरण के लिए, मैं यहां एक छात्र को वापस ला रहा हूं ... () तरीके यहां पर हैं - आनंद लें।


1

आप कब C ++ में कक्षा का उपयोग करना और कब कक्षा का उपयोग करना पसंद करेंगे?

structजब मैं परिभाषित करता हूं functorsऔर उपयोग करता हूं POD। अन्यथा मैं उपयोग करता हूं class

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
    bool operator()(int first, int second)
    { return first < second; }
};

class mycompare : public std::binary_function<int, int, bool>
{
public:
    bool operator()(int first, int second)
    { return first < second; }
};

1
यह उत्तर उम्र के लक्षण दिखा रहा है :) std::binary_function<>केवल पदावनत नहीं है, c ++ 17 इसे हटा भी देता है।
sehe

वास्तव में आश्चर्य की बात नहीं है क्योंकि यह सी ++ 03 के समय में लिखा गया था, 15 साल पहले परिभाषित की गई भाषा।
ऑर्बिट में

1

जब मैं POD प्रकार या फ़न्क्टर बनाने की आवश्यकता होती है तो मैं स्ट्रक्चर्स का उपयोग करता हूं।


1

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


0

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

जैसे: फाइलों और सॉकेट स्ट्रीम से डेटा पढ़ना / लिखना आदि फ़ंक्शन तर्कों को एक संरचना में पास करना जहां फ़ंक्शन तर्क बहुत अधिक हैं और फ़ंक्शन सिंटैक्स बहुत लंबा दिखता है।

तकनीकी रूप से डिफ़ॉल्ट एक्सेसिबिलिटी को छोड़कर क्लास और स्ट्रेंथ के बीच कोई बड़ा अंतर नहीं है। अधिक यह प्रोग्रामिंग शैली पर निर्भर करता है कि आप इसका उपयोग कैसे करते हैं।


-4

मुझे लगा कि स्ट्रक्चर्स को डेटा स्ट्रक्चर (सूचना का एक मल्टी-डेटा प्रकार सरणी) के रूप में इरादा किया गया था और कोड पैकेजिंग (सबरूटिन और फ़ंक्शन के संग्रह की तरह) के लिए कक्षाएं शुरू की गई थीं।

:(


-6

मैं C ++ में "स्ट्रक्चर" का उपयोग कभी नहीं करता।

मैं कभी ऐसे परिदृश्य की कल्पना नहीं कर सकता जहाँ आप निजी सदस्यों को चाहते समय एक संरचना का उपयोग करेंगे, जब तक कि आप जानबूझकर भ्रमित होने की कोशिश नहीं कर रहे हों।

ऐसा लगता है कि डेटा का उपयोग कैसे किया जाएगा इसका एक सिंटैक्टिक संकेत है, लेकिन इसका उपयोग करना अधिक है, लेकिन मैं सिर्फ एक वर्ग बनाऊंगा और कक्षा के नाम पर या टिप्पणियों के माध्यम से स्पष्ट करने का प्रयास करूंगा।

उदाहरण के लिए

class PublicInputData {
    //data members
 };

मेरे अनुसार, "डेटा का उपयोग कैसे किया जाएगा" एक सिंटैक्टिक संकेत एक संरचना का उपयोग करने के लिए एक पूरी तरह से अच्छा कारण है, खासकर अगर विकल्प का उपयोग क्लासनेम में एक टिप्पणी या एक नाम का उपयोग करना है।
विक्टर सेहर

2
structपहले से ही स्पष्ट रूप से घोषित नहीं किया जाएगा कि कक्षा के सदस्य डिफ़ॉल्ट रूप से, सार्वजनिक होंगे?
4
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.