क्या हमें कन्स्ट्रक्टर्स को स्ट्रक्चर्स में जोड़ना चाहिए?


14

हम अक्सर कक्षा के विपरीत डेटा संरचना को परिभाषित करने के लिए c ++ संरचना का उपयोग करते हैं जो सदस्य विधियों के साथ एक पूर्ण मॉड्यूल हो सकता है। अब गहराई से, हम जानते हैं कि वे दोनों एक ही हैं (शिथिल बोल)।

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

यदि मेरी डेटा संरचनाओं में डिफ़ॉल्ट कंस्ट्रक्टरों को जोड़ा जाता है, तो क्या वह फेक हो जाएगा?

क्या डिफॉल्ट कंस्ट्रक्टर को लागू करने से स्ट्रक्चर नॉन-पीओडी (प्लेन पुराना डेटा टाइप) भी हो जाता है, बशर्ते अन्य मापदंड पूरे हो जाएं?

चीजों को परिप्रेक्ष्य में रखने के लिए, एक साधारण उदाहरण पर विचार करें लेकिन वास्तव में संरचना बहुत बड़ी होगी।

struct method
{
    char    name[32];
    float   temperature;
    int     duration;
};

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

मुझे इसके निर्माता को लागू करने के बजाय हर बार ऑब्जेक्ट को इनिशियलाइज़ करने की जिम्मेदारी क्यों लेनी चाहिए जो इसकी गारंटी देता है?


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

यह इस बात पर निर्भर करता है कि ये निर्माणकर्ता क्या कर रहे हैं। मुझे लगता है कि एक साधारण संरचना पर एक निर्माता का होना पूरी तरह से उचित है अगर यह बुनियादी तरीकों से फ़ील्ड मान सेट कर रहा है।
रोबोट

@ डोवल यह सवाल नहीं है, मैंने पोस्ट को अपडेट किया। स्टीवन: हाँ कंस्ट्रक्टर केवल डिफ़ॉल्ट मान प्रदान करेंगे।
ज़ादेन

@StevenBurnap: निर्माता सिर्फ बुनियादी तरीकों से क्षेत्र मूल्य निर्धारित से ज्यादा कुछ भी होता है, तो यह केवल है अधिक उचित यह है करने के लिए। एक ढाँचे पर भी।
Jan Hudec

2
मेरा क्या मतलब है, यदि आप कंस्ट्रक्टर में जटिल तर्क ढूंढना शुरू करते हैं, तो संभावना है कि आपको इसे एक कक्षा में बनाना चाहिए। (IMHO) लेकिन यह वास्तव में केवल एक शैली का सवाल है, जो केवल वास्तविक अंतर के बीच है structऔर classयह है कि एक निजी और दूसरा सार्वजनिक रूप से चूकता है।
रोबोट

जवाबों:


13

कभी-कभी एक संरचना में कंस्ट्रक्टर को जोड़ना उचित होता है और कभी-कभी यह नहीं होता है।

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

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


8

साथ सी ++ 11 आप कर सकते हैं

struct method
{
    char    name[32] {};
    float   temperature = 42.141521;
    int     duration = -6;
};

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


-1

शीघ्र जवाब:

यह इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं।

लंबे, विस्तारित, बोरिंग उत्तर:

तुमने कील ठोक दी।

मैं आमतौर पर नापसंद करता हूं कि "सी ++" "संरचना (ओं)" को तरीकों की घोषणा करने की अनुमति देता है। अधिमानतः, मैं केवल आवश्यक फ़ील्ड के लिए और POD "संरचना (ओं)" के लिए स्पष्ट "क्लास (तों)" का उपयोग करता हूं।

फिर भी, मैं मानता हूं कि कुछ बुनियादी सरल ऑपरेशन, जैसे:

  • प्रारंभिक मान निर्दिष्ट करें ("निर्माता")
  • संरचना की प्रतिलिपि बनाएँ ("कॉपी निर्माता)
  • मौजूदा संरचना को मान निर्दिष्ट करें ("अधिभार असाइनर")

आवश्यक हैं, और, उन परिस्थितियों में, संरचनाओं के लिए तरीके, समझ में आते हैं।

सुझाव

एक और संभावित समाधान पीओडी संरचनाओं का उपयोग करना है, लेकिन, अभी भी वैचारिक रूप से उन्हें कक्षाओं और वस्तुओं के रूप में मानते हैं।

उन घोषणाओं को एक नाम स्थान में लपेटें, और, सबसे महत्वपूर्ण कार्यों के लिए वैश्विक कार्यों को जोड़ें।

कोड घोषणा इस तरह हो सकती है:

namespace Customers
{
  struct CustomerStruct
  {
    char[255] FirstName;
    char[255] LastName;
    int Age;
    bool IsAlive;
    bool IsMarried;
  }; // struct

  CustomerStruct* CreateCustomer
  (
    char* NewFirstName;
    char* NewLastName;
    int NewAge;
    bool NewIsAlive;
    bool NewIsMarried;
  )
  {
    CustomerStruct* NewCustomer = new CustomerStruct();
      NewCustomer->FirstName = NewFirstName;
      NewCustomer->LastName = NewLastName;
      NewCustomer->Age = NewAge;
      NewCustomer->IsAlive = NewIsAlive;
      NewCustomer->IsMarried = NewIsMarried;
    return NewCustomer;
  } // CustomerStruct* CreateCustomer (...)

} // namespace

समाधान लागू करने वाला कोड कुछ इस तरह हो सकता है:

#include <Customers>

using Customers;

int main (...)
{
   int ErrorCode = 0;

   CustomerClass* ThisCustomer =
     Customers::CreateCustomer
      ("John", "Doe", 23, true, true);

   // do something with "ThisCustomer"

   delete ThisCustomer;

   return ErrorCode;
} // int main(...)

यह वैकल्पिक दृष्टिकोण बेहतर है जब डेटा का एक विशाल मेमोरी आवंटन आवश्यक है, या अन्य निम्न-स्तरीय साझा पुस्तकालयों के साथ बातचीत कर रहा है।

कुछ बदलावों के साथ इस दृष्टिकोण को गेम डेवलपमेंट में लागू किया गया है।

अतिरिक्त

व्यक्तिगत रूप से, मैं "C ++" के लिए एक वाक्यविन्यास विस्तार पर विचार करता हूं, या यहां तक ​​कि एक नया "C ++" आधारित PL जो इस हल को हल करता है:

// "Plain Old Data" Structure
// No Methods, No "Functors", allowed
strict struct CustomerStruct
{
  char[255] FirstName;
  char[255] LastName;
  int Age;
  bool IsAlive;
  bool IsMarried;
}; // strict struct

// Object Oriented "Plain Old Data" Structure
// Yes, Methods and "Functors" allowed
relaxed struct CustomerStruct
{
  char[255] FirstName;
  char[255] LastName;
  int Age;
  bool IsAlive;
  bool IsMarried;

  public void Foo();
  public void Bar();

  public (void*) (SomeFunctor) ();
}; // relaxed struct

// Class and Object Oriented
class CustomerClass
{
  public char[255] FirstName;
  public char[255] LastName;
  public int Age;
  public bool IsAlive;
  public bool IsMarried;

  public void Foo();
  public void Bar();
}; // class

चीयर्स।

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