2017-09-18 18 views
16

में केवल पढ़ने योग्य संपत्ति के रूप में संदर्भ संदर्भ फ़ील्ड सी ++ कक्षाओं में एक पाठक गेटटर के रूप में एक कॉन्स्ट संदर्भ फ़ील्ड का उपयोग करना अच्छा है?सी ++ वर्ग

मेरा मतलब है, क्या यह कोड अच्छी प्रथाओं को पूरा करता है?

class check{ 
private: 
    int _x; 
public: 
    const int& x = _x; 
    void setX(int v){ 
     _x = v; 
    } 
}; 

यह बहुत सी # गुण, IMHO की तरह काम कर रहा है, और बहुत आसान और वर्ग उपयोग कोड में साफ:

check s; 
    int i; 
    std::cin >> i; 
    s.setX(i); 
    std::cout << s.x << '\n'; 
    s.setX(7); 
    // s.x = i; // Error 
    std::cout<<s.x<<'\n'; 
+4

और इसे विस्मरण के लिए कास्ट किया जा सकता है :) – StoryTeller

+5

नहीं, यह एक बुरा अभ्यास है क्योंकि इस संदर्भ को संग्रहीत करने से एक सीधी मेलाइन गेटटर फ़ंक्शन की तुलना में अतिरिक्त मेमोरी ओवरहेड हो सकता है। एक और बात यह है कि आप मूल्य तक पहुंचने के बावजूद रनटाइम चेक/आवेषण निष्पादित करने में सक्षम नहीं होंगे। दुर्भाग्य से सी # गुणों का अनुकरण करने के लिए कोई वास्तविक तरीका नहीं है-सिंटैक्स की तरह। एक [एमएस-विशिष्ट 'संपत्ति' एक्सटेंशन] (https://docs.microsoft.com/en-us/cpp/cpp/property-cpp) था लेकिन वे गैर-मानक हैं और उन्हें छोड़ दिया गया था। – VTT

+11

किसी को 'चेक' असाइन करने का प्रयास करें। – molbdnilo

उत्तर

19

इस कोड को करना अच्छी प्रथाओं को पूरा?

वास्तव में, क्योंकि यह अनावश्यक जटिलता और अंतरिक्ष ओवरहेड पेश करता है।

इसके अलावा, आप मूल्य के उपयोग के बावजूद रनटाइम चेक और/या दावे निष्पादित करने में सक्षम नहीं होंगे।

इसके अलावा, जीवनकाल और अर्थशास्त्र के साथ क्या होता है?

अपने कोड में एक और check असाइन करने का प्रयास करें और देखें कि क्या होता है। असाइनमेंट खराब बना हुआ है क्योंकि कक्षा गैर-असाइन करने योग्य है। संदर्भ की देखभाल करने के लिए आपको एक प्रतिलिपि प्रदान करना चाहिए और कन्स्ट्रक्टर को स्थानांतरित करना चाहिए, ताकि यह पुराने ऑब्जेक्ट के डेटा सदस्य को संदर्भित न करे।

बेहतर उपयोग _x सीधे और एक सीधा इनलाइन गेटर फ़ंक्शन है।


पुनश्च: C#-like properties in native C++?

+0

'कोशिश करें अपने कोड में दूसरे को एक चेक असाइन करना और देखें कि क्या होता है। आपकी ऑब्जेक्ट की प्रतिलिपि बनाई गई है 'नहीं, यह नहीं है। असाइनमेंट खराब बना हुआ है क्योंकि कक्षा गैर-असाइन करने योग्य है। – user2079303

+0

कॉपी करने का मुद्दा केवल इसका मतलब है कि आपको प्रतिलिपि बनाना और रचनाकारों को स्थानांतरित करना है जो सुनिश्चित करते हैं कि संदर्भ स्थानीय ऑब्जेक्ट में इंगित करता है। असाइनमेंट कोई समस्या नहीं है, क्योंकि किसी भी असाइनमेंट ऑपरेटर में किसी संदर्भ को बदलना असंभव है, और एक विनाशक भी आवश्यक नहीं है। – cmaster

6

आम तौर पर, यह नहीं एक अच्छा अभ्यास है।

इमो, और कक्षा उपयोग कोड में बहुत आसान और साफ है।

यह स्पष्ट और आसान क्यों होना चाहिए?

  • आप एक और चर सदस्य (बेकार ओवरहेड) पेश करते हैं। (आम तौर पर, संदर्भ एक अतिरिक्त सदस्य सूचक के रूप में लागू किया जाएगा)।
  • यह कोड को बनाए रखने के लिए कठिन बनाता है। आप वास्तव में परिवर्तनीय सदस्यों के बीच निर्भरता बना रहे हैं।
  • यह असाइनमेंट और प्रतिलिपि संचालन में समस्या बनाता है। कॉपी ऑपरेशन कैसे काम करना चाहिए?

"क्लासिक" दृष्टिकोण ध्वनि मेरे द्वारा स्पष्ट है, उदा .:

class Foo { 
public: 
    void set_num(int value) noexcept { m_num = value; } 
    int get_num() const noexcept { return m_num; } 
    void set_string(std::string value) noexcept { 
     m_str = std::move(value); 
    } 
    const std::string& get_string() const noexcept { 
     return m_str; 
    } 
private: 
    int m_num; 
    std::string m_str; 
}; 
देखने के एक प्रदर्शन बिंदु से

, इस दृष्टिकोण प्राथमिकता दी जानी चाहिए।

  • समय जटिलता: एक इनलाइन समारोह पर get_variable फोन अपने "संदर्भ दृष्टिकोण" की तुलना में अधिक भूमि के ऊपर का परिचय नहीं है। इसके अलावा, यह संकलक द्वारा अत्यधिक अनुकूलन योग्य है (कोड के सीधा होने के कारण)।
  • अंतरिक्ष जटिलता: यह अतिरिक्त डेटा सदस्य पेश नहीं करता है।
4

आप क्या प्रस्ताव सामान्य एक बुरा विचार में है:

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

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

class Cheque { 
public: 
    int x() const { 
     return x_; 
    } 
    Cheque & x(int newX) { 
     x_ = newX; 
     return *this; 
    } 
private: 
    int x_; 
} 

// Usage: 
// int amt = myCheque.x(1234); 
// Cheque c = Cheque().x(123); 

ऊपर कोड आप method chaining उपयोग करने के लिए सक्षम के रूप *this रिटर्निंग; Fluent interface मुहावरे को लागू करने का एक तरीका।

1

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

using System; 

namespace Reflect 
{ 
    class Program 
    { 
     class X 
     { 
      public int Prop { get; set; } 
     } 

     static void Main(string[] args) 
     { 
      var type = typeof(X); 
      foreach (var method in type.GetMethods()) 
      { 
       Console.WriteLine(method.Name); 
      } 
      Console.ReadKey(); 
     } 
    } 
} 

आपका आउटपुट होना चाहिए::

get_Prop 
set_Prop 
ToString 
Equals 
GetHashCode 
GetType 

get_Prop समारोह है कि गेटर लागू करता है

यहाँ कुछ सी # कोड है कि इस तथ्य को साबित करता है है। set_Prop वह फ़ंक्शन है जो सेटर लागू करता है।

तो यदि आप जो भी कर रहे हैं, वही भी दिखता है, यह बिल्कुल समान नहीं है।

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

बस गेटर्स और सेटर्स के साथ रहना सीखें। गेटर्स और सेटर्स अच्छे अभ्यास हैं। वे छोटे हैं, वे सरल हैं, वे लचीले हैं, वे आमतौर पर इनलाइनिंग के लिए अच्छे उम्मीदवार हैं, हर कोई समझता है कि वे क्या करते हैं और क्या करते हैं।

संबंधित मुद्दे