c++ - सी++ में एक वर्ग बनाम एक स्ट्रक्चर का उपयोग कब करना चाहिए?




oop class (16)

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

जब मैं functors और POD परिभाषित करता हूं तो मैं struct उपयोग करता हूं। अन्यथा मैं 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; }
};

सी ++ में एक class बनाम एक class का उपयोग करना बेहतर परिदृश्य में कौन सा परिदृश्य है?


कक्षा।

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

class test_one {
    int main_one();
};

के बराबर है

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

तो अगर आप कोशिश करते हैं

int two = one.main_one();

हमें एक त्रुटि main_one is private : 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;
};

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


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

// 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

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


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

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);
}

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


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


जब मैं पीओडी प्रकार या मज़ेदार बनाने की ज़रूरत है तो मैं structs का उपयोग करता हूं।


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

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

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

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

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


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

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


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

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

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

उदाहरण के लिए

class PublicInputData {
    //data members
 };

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

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

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


मौजूदा उत्तरों में बहुत सारी गलत धारणाएं हैं।

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

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

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

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

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

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

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

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

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

class Foo;
struct Bar;

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

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

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

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


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

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


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

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


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

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

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

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

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


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

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


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

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

struct एस और class ईएस के बीच अंतर करना बहुत मुश्किल है, जो हमें करना चाहिए - प्रोग्रामिंग। सी ++ की कई समस्याओं की तरह, यह पीछे की संगतता की मजबूत इच्छा से उत्पन्न होता है।





ooad