[c++] फ़ंक्शन पैरामीटर के लिए 'कॉन्स्ट' का उपयोग करें


Answers

"कॉन्स व्यर्थ है जब तर्क मूल्य से गुजरता है क्योंकि आप कॉलर के ऑब्जेक्ट को संशोधित नहीं करेंगे।"

गलत।

यह आपके कोड और आपकी मान्यताओं को स्वयं-दस्तावेज करने के बारे में है।

यदि आपके कोड में बहुत से लोग काम कर रहे हैं और आपके कार्य गैर-तुच्छ हैं तो आपको किसी भी चीज और "सब कुछ" को चिह्नित करना चाहिए। औद्योगिक-शक्ति कोड लिखते समय, आपको हमेशा यह मानना ​​चाहिए कि आपके सहकर्मी मनोचिकित्सक हैं जो वे आपको प्राप्त करने की कोशिश कर रहे हैं (विशेष रूप से जब यह भविष्य में अक्सर होता है)।

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

Question

आप const साथ कितने दूर जाते हैं? क्या आप जरूरी होने पर फंक्शंस const बनाते हैं या आप पूरे हॉग पर जाते हैं और इसे हर जगह इस्तेमाल करते हैं? उदाहरण के लिए, एक साधारण म्यूटेटर की कल्पना करें जो एक एकल बूलियन पैरामीटर लेता है:

void SetValue(const bool b) { my_val_ = b; }

क्या वह आधार वास्तव में उपयोगी है? निजी तौर पर मैं पैरामीटर समेत इसे व्यापक रूप से उपयोग करने का विकल्प चुनता हूं, लेकिन इस मामले में मुझे आश्चर्य है कि यह सार्थक है या नहीं?

मैं यह जानकर भी हैरान था कि आप फ़ंक्शन घोषणा में पैरामीटर से const को छोड़ सकते हैं लेकिन इसे फ़ंक्शन परिभाषा में शामिल कर सकते हैं, उदाहरण के लिए:

एच फाइल

void func(int n, long l);

.cpp फ़ाइल

void func(const int n, const long l)

क्या इसका कोई कारण है? यह मेरे लिए थोड़ा असामान्य लगता है।




कॉन्स सी ++ में डिफ़ॉल्ट होना चाहिए था। इस कदर :

int i = 5 ; // i is a constant

var int i = 5 ; // i is a real variable



निम्नलिखित दो पंक्तियां कार्यात्मक रूप से समकक्ष हैं:

int foo (int a);
int foo (const int a);

जाहिर है कि अगर आप दूसरे तरीके से परिभाषित हैं, तो आप foo के शरीर में संशोधित नहीं कर पाएंगे, लेकिन बाहर से कोई अंतर नहीं है।

जहां वास्तव में आसानी से आता है संदर्भ या सूचक पैरामीटर के साथ है:

int foo (const BigStruct &a);
int foo (const BigStruct *a);

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

*: जब तक यह कॉन्स्टेस को दूर नहीं करता है, लेकिन यह एक और पोस्ट है।







चिह्नित मान पैरामीटर 'कॉन्स्ट' निश्चित रूप से एक व्यक्तिपरक चीज है।

हालांकि मैं वास्तव में आपके उदाहरण में वैल्यू पैरामीटर कॉन्स को चिह्नित करना पसंद करता हूं।

void func(const int n, const long l) { /* ... */ }

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

एक संक्षिप्त कार्य के लिए, यह तर्कसंगत रूप से 'कॉन्स्ट' रखने के लिए समय / स्थान की बर्बादी है, क्योंकि आमतौर पर यह स्पष्ट है कि तर्क फ़ंक्शन द्वारा संशोधित नहीं होते हैं।

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

मैं सुनिश्चित कर सकता हूं कि अगर मैं 'एन' और 'एल' के साथ कुछ गणना करता हूं, तो मैं अलग-अलग परिणाम प्राप्त करने के डर के बिना उस गणना को पुन: सक्रिय / स्थानांतरित कर सकता हूं क्योंकि मुझे ऐसी जगह याद आती है जहां एक या दोनों बदल जाते हैं।

चूंकि यह एक कार्यान्वयन विवरण है, इसलिए आपको हेडर में मान पैरामीटर को घोषित करने की आवश्यकता नहीं है, जैसे कि आपको कार्यान्वयन के उपयोग के समान नामों के साथ फ़ंक्शन पैरामीटर घोषित करने की आवश्यकता नहीं है।




Being a VB.NET programmer that needs to use a C++ program with 50+ exposed functions, and a .h file that sporadically uses the const qualifier, it is difficult to know when to access a variable using ByRef or ByVal.

Of course the program tells you by generating an exception error on the line where you made the mistake, but then you need to guess which of the 2-10 parameters is wrong.

So now I have the distasteful task of trying to convince a developer that they should really define their variables (in the .h file) in a manner that allows an automated method of creating all of the VB.NET function definitions easily. They will then smugly say, "read the ... documentation."

I have written an awk script that parses a .h file, and creates all of the Declare Function commands, but without an indicator as to which variables are R/O vs R/W, it only does half the job.

संपादित करें:

At the encouragement of another user I am adding the following;

Here is an example of a (IMO) poorly formed .h entry;

typedef int (EE_STDCALL *Do_SomethingPtr)( int smfID, const char* cursor_name, const char* sql );

The resultant VB from my script;

    Declare Function Do_Something Lib "SomeOther.DLL" (ByRef smfID As Integer, ByVal cursor_name As String, ByVal sql As String) As Integer

Note the missing "const" on the first parameter. Without it, a program (or another developer) has no Idea the 1st parameter should be passed "ByVal." By adding the "const" it makes the .h file self documenting so that developers using other languages can easily write working code.




आह, एक कठिन है। एक तरफ, एक घोषणा एक अनुबंध है और यह वास्तव में मूल्य द्वारा एक कॉन्स्ट तर्क को पारित करने के लिए समझ में नहीं आता है। दूसरी तरफ, यदि आप फ़ंक्शन कार्यान्वयन को देखते हैं, तो आप संकलक को स्थिर करने की अधिक संभावनाएं देते हैं यदि आप निरंतर तर्क घोषित करते हैं।




Comp.lang.c ++ पर पुरानी "सप्ताह के गुरु" लेखों में इस विषय पर एक अच्छी चर्चा है। here नियंत्रित।

संबंधित GOTW आलेख here हर्ब सटर की वेबसाइट पर उपलब्ध here




यदि आप ->* या .* ऑपरेटर का उपयोग करते हैं, तो यह जरूरी है।

यह आपको कुछ लिखने से रोकता है

void foo(Bar *p) { if (++p->*member > 0) { ... } }

जो मैंने अभी लगभग किया था, और संभवतः जो भी आप चाहते हैं वह नहीं करता है।

मैं क्या कहना चाहता था

void foo(Bar *p) { if (++(p->*member) > 0) { ... } }

और अगर मैंने Bar * और p बीच एक const डाला था, तो कंपाइलर ने मुझे यह बताया होगा।




मैं मूल्य-पारित पैरामीटर के लिए कॉन्स्ट का उपयोग नहीं करता हूं। कॉलर परवाह नहीं है कि आप पैरामीटर को संशोधित करते हैं या नहीं, यह कार्यान्वयन विवरण है।

वास्तव में महत्वपूर्ण बात यह है कि यदि वे अपने उदाहरण को संशोधित नहीं करते हैं तो विधियों को आधार के रूप में चिह्नित करना है। ऐसा करने के बाद ऐसा करें, क्योंकि अन्यथा आप या तो बहुत सारे const_cast <> के साथ समाप्त हो सकते हैं या आप पाते हैं कि एक विधि को चिह्नित करने के लिए बहुत सारे कोड को बदलने की आवश्यकता है क्योंकि यह अन्य विधियों को कॉल करता है जिन्हें चिह्नित किया जाना चाहिए था।

अगर मुझे उन्हें संशोधित करने की आवश्यकता नहीं है तो मैं स्थानीय वर्र्स कॉन्स को भी चिह्नित करता हूं। मेरा मानना ​​है कि यह "चलती भागों" की पहचान करना आसान बनाकर कोड को समझना आसान बनाता है।




There's really no reason to make a value-parameter "const" as the function can only modify a copy of the variable anyway.

The reason to use "const" is if you're passing something bigger (eg a struct with lots of members) by reference, in which case it ensures that the function can't modify it; or rather, the compiler will complain if you try to modify it in the conventional way. It prevents it from being accidentally modified.




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




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




All the consts in your examples have no purpose. C++ is pass-by-value by default, so the function gets copies of those ints and booleans. Even if the function does modify them, the caller's copy is not affected.

So I'd avoid extra consts because

  • They're redudant
  • They clutter up the text
  • They prevent me from changing the passed in value in cases where it might be useful or efficient.



मैं इस तरह के पैरामीटर पर कॉन्स्ट नहीं डालूंगा - हर कोई पहले से ही जानता है कि एक बूलियन (एक बुलियन के विपरीत) और स्थिर है, इसलिए इसे जोड़ने से लोग सोचेंगे "प्रतीक्षा करें, क्या?" या यहां तक ​​कि आप संदर्भ द्वारा पैरामीटर पारित कर रहे हैं।




Related



Tags

c++ c++   const