2008-09-25 13 views
86

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

  1. यह हर बार जब मैं स्थिरांक के रूप में कुछ निशान की तरह लगता है, मैं कोई त्रुटि मिलती है और कुछ अन्य समारोह कहीं बदलने के लिए स्थिरांक भी रहना होगा। इसके बाद मुझे अन्य फ़ंक्शन कहीं और बदलना पड़ता है। क्या यह ऐसा कुछ है जो अनुभव के साथ आसान हो जाता है?

  2. क्या वास्तव में का उपयोग करने के लाभ मुसीबतों की भरपाई के लिए पर्याप्त हैं? यदि आप किसी ऑब्जेक्ट को बदलने का इरादा नहीं रखते हैं, तो क्यों न केवल कोड लिखें जो इसे नहीं बदलेगा?

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

void foo(const int DEFCON) 
{ 
    if (DEFCON = 1)  //< FLAGGED AS COMPILER ERROR! WORLD SAVED! 
    { 
     fire_missiles(); 
    } 
} 
+0

8yr पुराना पूर्वदर्शी, लेकिन .. आपके कोड को 100x तेज करने के बारे में (यह लाइव देखा गया)? – lorro

+1

मेरा उत्तर यहां देखें (संबंधित प्रश्न, मैं वही जवाब कहूंगा): http://stackoverflow.com/questions/42310477/declare-value-in-c-header?answertab=active#tab-top बीटीडब्ल्यू: I प्यार करें 'const' –

उत्तर

121

यह "कॉन्स्ट शुद्धता" पर एक निश्चित लेख है: https://isocpp.org/wiki/faq/const-correctness

संक्षेप में, स्थिरांक का उपयोग कर अच्छा अभ्यास है, क्योंकि ...

  1. यह गलती से बदल रहा है चर का इरादा नहीं है बदला जा से बचाता है
  2. यह आप आकस्मिक चर कार्य करने से रक्षा करता है, और
  3. कंपाइलर इसे अनुकूलित कर सकता है। क्योंकि यह वास्तव में जानता है क्या चर/समारोह के राज्य में हर समय हो जाएगा उदाहरण के लिए, आप से

    if(x = y) // whoops, meant if(x == y) 
    

सुरक्षित है इसी समय, संकलक और अधिक कुशल कोड उत्पन्न कर सकते हैं। यदि आप तंग सी ++ कोड लिख रहे हैं, तो यह अच्छा है।

आप सही हैं कि लगातार स्थिरता का उपयोग करना मुश्किल हो सकता है, लेकिन अंत कोड प्रोग्राम के साथ अधिक संक्षिप्त और सुरक्षित है। जब आप बहुत सी ++ विकास करते हैं, तो इसका लाभ तुरंत प्रकट होता है।

+0

मैंने हमेशा यह माना कि कॉन्स वैल्यू को स्वतंत्र रूप से कैश किया जा सकता है और इस प्रकार कई समवर्ती मुद्दों से बचें या गति में सुधार हो सकता है। क्या यह सच है? –

+2

निश्चित रूप से। 'const' चर * * गति में सुधार कर सकते हैं कि संकलक अधिक इष्टतम कोड उत्पन्न कर सकता है क्योंकि यह पूर्ण इरादा और चर के उपयोग को जानता है। क्या आप अंतर देखेंगे? खैर, यह आपके आवेदन पर बहस योग्य है। जहां तक ​​समेकन का संबंध है, कॉन्स-वेरिएबल्स केवल पढ़ने के लिए हैं, जिसका मतलब है कि उन चरों पर विशेष ताले की आवश्यकता नहीं है क्योंकि मान हमेशा एक जैसा होगा। –

+2

सी ++ 11 के रूप में मानक लाइब्रेरी थ्रेड-सुरक्षित का मतलब है और अपने कोड का इलाज करने के लिए 'कॉन्स' मानता है इस तरह संभावित बहु-थ्रेडिंग समस्याओं की जांच करना आसान बनाता है और आपके एपीआई के लिए एपीआई गारंटी प्रदान करने का एक आसान तरीका है उपयोगकर्ताओं। – pmr

109

यहां एक सामान्य त्रुटि है कि स्थिरांक शुद्धता के खिलाफ आप की रक्षा कर सकते के साथ कोड का एक टुकड़ा है। यह एक बहुत सीधी आगे की राय है लेकिन उम्मीद है कि यह कुछ मदद करता है।

+8

तो हम कह रहे हैं कि कॉन्स आवश्यक है क्योंकि कुछ खूनी बेवकूफ ने सी में असाइनमेंट ऑपरेटर के रूप में "=" चुना है? ;-) –

+26

बेशक, अधिकांश आधुनिक कंपाइलर्स सशर्त में असाइनमेंट के बारे में चेतावनी देते हैं और हम सभी उपचार चेतावनियों को त्रुटियों के झंडे के रूप में चालू करते हैं, दाएं: -> –

+0

बेशक, चूंकि फू को डेफॉन की अपनी निजी प्रतिलिपि मिलती है, असली वैसे भी डेफॉन मूल्य अपरिवर्तित होगा। – Eclipse

4

एक अच्छा लेख here ग में स्थिरांक के बारे में नहीं है ++:

24

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

+1

का उपयोग करें यह केवल सत्य है। कॉन्स को सुरक्षा के रूप में भी इंटरफेस के माध्यम से इन-चर को लागू करने के लिए उपयोग किया जाता है। –

+0

यह है, लेकिन आप अनुशासित कोडिंग प्रथाओं और पोस्टर राज्यों के माध्यम से इसे लागू कर सकते हैं।वास्तविक लाभ एपीआई में दिखाई देने से आता है। –

+2

बिल्कुल। "कॉन्स इंट वैल्यू = 5;" होना बेहतर है "int ConstValue = 5;" से अधिक है। +1। – paercebal

11

const आपको कोड को अलग करने में मदद करता है जो आपकी पीठ के पीछे "चीजें बदलता है"। तो, एक कक्षा में, आप उन सभी विधियों को चिह्नित करेंगे जो ऑब्जेक्ट की स्थिति को const के रूप में नहीं बदलते हैं।इसका मतलब है कि const उस वर्ग के उदाहरण अब किसी भी गैर-const विधियों को कॉल करने में सक्षम नहीं होंगे। इस तरह, आपको गलती से कार्यक्षमता को कॉल करने से रोका जा सकता है जो आपकी ऑब्जेक्ट को बदल सकता है।

इसके अलावा, const अधिभार तंत्र का हिस्सा है, इसलिए आपके पास समान हस्ताक्षर वाले दो विधियां हो सकती हैं, लेकिन const और बिना किसी के। const वाला एक const संदर्भों के लिए बुलाया जाता है, और दूसरा को गैर-const संदर्भों के लिए बुलाया जाता है।

उदाहरण:

#include <iostream> 

class HelloWorld { 
    bool hw_called; 

public: 
    HelloWorld() : hw_called(false) {} 

    void hw() const { 
     std::cout << "Hello, world! (const)\n"; 
     // hw_called = true; <-- not allowed 
    } 

    void hw() { 
     std::cout << "Hello, world! (non-const)\n"; 
     hw_called = true; 
    } 
}; 

int 
main() 
{ 
    HelloWorld hw; 
    HelloWorld* phw1(&hw); 
    HelloWorld const* phw2(&hw); 

    hw.hw(); // calls non-const version 
    phw1->hw(); // calls non-const version 
    phw2->hw(); // calls const version 
    return 0; 
} 
1

मैं स्थिरांक शुद्धता ... सिद्धांत रूप में पसंद करते हैं। हर बार जब मैंने इसे अभ्यास में कठोर रूप से लागू करने की कोशिश की है तो यह अंततः टूट गया है और कोड को बदसूरत बनाने में const_cast शुरू हो गया है।

शायद यह केवल डिजाइन पैटर्न है जो मैं उपयोग करता हूं, लेकिन कॉन्स हमेशा ब्रश होने के कारण समाप्त होता है।

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

शायद उत्तर को कॉन्स्ट-नेस आवश्यकताओं के आधार पर कक्षा को विभाजित करना है, लेकिन यह उस लाभ को जटिल बनाने के लिए है जो मैं लाता हूं।

+0

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

+2

एक सम्मिलित() फ़ंक्शन को तब तक चिह्नित किया जाएगा जब तक इसका गलत नाम न हो? चीजों को जोड़ना आमतौर पर उस चीज़ को संशोधित करता है जिसे आपने इसे जोड़ा है, जिसका अर्थ है कि यह आधार नहीं है। आप वास्तव में क्या चाहते थे एक tableWithConstSchema था। –

+0

मैं एक और कक्षा जोड़ सकता हूं, लेकिन मैं एपीआई को अस्थिर रूप से जटिलता के लिए अनावश्यक रूप से जटिल नहीं बनाना चाहता हूं। –

2

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

हां, यह समय के साथ आसान हो जाता है।

49

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

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

+3

इससे मुझे इतनी सारी बग्स को रोकने में मदद मिली है जहां मेरे पास एक गैर-कॉन्स्ट फ़ंक्शन कॉल करने के बारे में एक कॉन्स्ट फ़ंक्शन था क्योंकि मैं भूल गया था कि यह नीचे डेटा संशोधित करता है। –

+5

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

+0

यह मेरे अनुभव में पूरी तरह से गलत है। नेस्टेड पॉइंट प्रकार इस प्रकार की चीज़ के लिए सबसे बड़ा सिरदर्द बनाता है, जहां आप एक ही प्रकार में एकाधिक कॉन्स-क्वांटिफायर रख सकते हैं। – Noldorin

14

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

20

कॉन्स एक ऐसा वादा है जो आप डेवलपर के रूप में बना रहे हैं, और लागू करने में संकलक की सहायता को शामिल करते हैं।

होने के लिए मेरे कारणों स्थिरांक-सही:

  • यह अपने समारोह के ग्राहकों है कि आपके चर परिवर्तन नहीं होगा या स्थिरांक संदर्भ द्वारा
  • स्वीकारना तर्क आपत्ति आप संदर्भ द्वारा पारित करने की दक्षता देता है संचार मूल्य से गुजरने की सुरक्षा के साथ।
  • अपने इंटरफेस को सही कॉन्स्ट के रूप में लिखना ग्राहकों को उनका उपयोग करने में सक्षम करेगा। यदि आप गैर-कॉन्स संदर्भों को लेने के लिए अपना इंटरफ़ेस लिखते हैं, तो ग्राहक जो आपके साथ काम करने के लिए कॉन्स्टेंस का उपयोग कर रहे हैं, को स्थिरता डालने की आवश्यकता होगी। यह विशेष रूप से परेशान है यदि आपका इंटरफ़ेस गैर-कॉन्स्ट char * स्वीकार करता है, और आपके क्लाइंट std :: स्ट्रिंग का उपयोग कर रहे हैं, क्योंकि आप केवल उनसे एक कॉन्स char * प्राप्त कर सकते हैं।
  • कॉन्स का उपयोग करके आपको ईमानदार रखने में संकलक को सूचीबद्ध किया जाएगा ताकि आप गलती से कुछ ऐसा नहीं बदल सकें जो बदलना नहीं चाहिए।
12
एम्बेडेड प्रोग्रामिंग के लिए

, const विवेकपूर्ण तरीके से उपयोग करते समय वैश्विक डाटा संरचनाओं की घोषणा बूट समय में राम को कॉपी किए बिना ही पैदा कर रहा ROM या फ्लैश में स्थित होने का निरंतर डेटा से रैम की एक बहुत कुछ बचा सकता है।

रोज़ाना प्रोग्रामिंग में, const का उपयोग करके सावधानीपूर्वक उन प्रोग्रामों को लिखने से बचने में मदद मिलती है जो अप्रत्याशित रूप से क्रैश या व्यवहार करते हैं क्योंकि वे स्ट्रिंग अक्षर और अन्य निरंतर वैश्विक डेटा को संशोधित करने का प्रयास करते हैं।

बड़ी परियोजनाओं पर अन्य प्रोग्रामर के साथ काम करते समय, const का उपयोग करके अन्य प्रोग्रामर आपको थ्रॉटलिंग से रोकने में मदद करता है।

5

कहें कि आपके पास पाइथन में एक चर है। आप जानते हैं कि आप इसे संशोधित करने के लिए नहीं मानते हैं। अगर आप गलती से करते हैं तो क्या होगा?

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

1

आप प्रति निम्नलिखित कोड

#include <string> 

void f(const std::string& s) 
{ 

} 
void x(std::string& x) 
{ 
} 
void main() 
{ 
    f("blah"); 
    x("blah"); // won't compile... 
} 
16

प्रोग्रामिंग सी के साथ ही स्थिरांक साथ संकलक संकेत दे सकते हैं .... ++ स्थिरांक के बिना पर सुरक्षा बेल्ट के बिना ड्राइविंग की तरह है।

कार में कदम उठाने पर हर बार सुरक्षा बेल्ट डालने का दर्द होता है, और 365 दिनों में से 364 आप सुरक्षित रूप से पहुंचेंगे।

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

19

यदि आप दृढ़ता से दृढ़ता से उपयोग करते हैं, तो आप आश्चर्यचकित होंगे कि अधिकांश कार्यों में कितने वास्तविक चर हैं। अक्सर एक लूप काउंटर से अधिक नहीं। यदि आपका कोड उस बिंदु तक पहुंच रहा है, तो आप अंदर एक गर्म महसूस कर रहे हैं ... संकलन द्वारा सत्यापन ... कार्यात्मक प्रोग्रामिंग का दायरा पास है ... आप इसे लगभग स्पर्श कर सकते हैं ...

8

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

कोड है कि मैं लिख सकते हैं, का एक बहुत में अपने क्योंकि हम रचना एक बहुत का उपयोग करते हैं वास्तव में प्रयास के लायक हो गया:

class A { ... } 
class B { A m_a; const A& getA() const { return m_a; } }; 

हम स्थिरांक-शुद्धता नहीं था, तो आप करने के लिए होगा खुद को आश्वस्त करने के लिए जटिल वस्तुओं को वापस करने का उपाय करें कि कोई भी आपकी पीठ के पीछे कक्षा बी की आंतरिक स्थिति में हेरफेर नहीं कर रहा था।

संक्षेप में, कॉन्स-शुद्धता सड़क पर दर्द से बचाने के लिए एक रक्षात्मक प्रोग्रामिंग तंत्र है।

1

बिना स्थिरता के आप भी कॉन्स्ट संदर्भ द्वारा तर्क पारित नहीं कर सकते हैं, जिससे अधिक प्रतिलिपि हो सकती है। द्वारा पारित (गैर कॉन्स) संदर्भ एक सॉल्शन नहीं है क्योंकि गैर कॉन्स संदर्भ अस्थायी नहीं हो सकते हैं।

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