const
इन जैसी घोषणाओं का क्या अर्थ है ? const
मुझे confuses।
class foobar
{
public:
operator int () const;
const char* foo() const;
};
const
इन जैसी घोषणाओं का क्या अर्थ है ? const
मुझे confuses।
class foobar
{
public:
operator int () const;
const char* foo() const;
};
जवाबों:
जब आप const
कीवर्ड को एक विधि में जोड़ते हैं तो this
पॉइंटर अनिवार्य रूप से const
ऑब्जेक्ट के लिए पॉइंटर बन जाएगा , और इसलिए आप किसी भी सदस्य डेटा को बदल नहीं सकते हैं। (जब तक आप उपयोग नहीं करते हैं mutable
, उस पर और बाद में)।
const
कीवर्ड कार्यों हस्ताक्षर जिसका अर्थ है कि आप इसी तरह के दो तरीकों, जिनमें जब वस्तु है कहा जाता है लागू कर सकते हैं का हिस्सा है const
, और एक है कि नहीं है।
#include <iostream>
class MyClass
{
private:
int counter;
public:
void Foo()
{
std::cout << "Foo" << std::endl;
}
void Foo() const
{
std::cout << "Foo const" << std::endl;
}
};
int main()
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
}
यह आउटपुट करेगा
Foo
Foo const
नॉन-कास्ट विधि में आप उदाहरण के सदस्यों को बदल सकते हैं, जो आप const
संस्करण में नहीं कर सकते । यदि आप उपरोक्त उदाहरण में विधि घोषणा को कोड में बदलते हैं, तो आपको कुछ त्रुटियां मिलेंगी।
void Foo()
{
counter++; //this works
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; //this will not compile
std::cout << "Foo const" << std::endl;
}
यह पूरी तरह से सच नहीं है, क्योंकि आप एक सदस्य को चिह्नित कर सकते हैं mutable
और एक const
विधि फिर इसे बदल सकती है। यह ज्यादातर आंतरिक काउंटर और सामान के लिए उपयोग किया जाता है। उस के लिए समाधान नीचे कोड होगा।
#include <iostream>
class MyClass
{
private:
mutable int counter;
public:
MyClass() : counter(0) {}
void Foo()
{
counter++;
std::cout << "Foo" << std::endl;
}
void Foo() const
{
counter++; // This works because counter is `mutable`
std::cout << "Foo const" << std::endl;
}
int GetInvocations() const
{
return counter;
}
};
int main(void)
{
MyClass cc;
const MyClass& ccc = cc;
cc.Foo();
ccc.Foo();
std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << std::endl;
}
जो उत्पादन होगा
Foo
Foo const
Foo has been invoked 2 times
कास्ट का मतलब है कि विधि वर्ग के किसी भी सदस्य को बदलने का वादा नहीं करती है। आप ऑब्जेक्ट के सदस्यों को निष्पादित करने में सक्षम होंगे जो कि इतने चिह्नित हैं, भले ही वह वस्तु स्वयं चिह्नित हो const
:
const foobar fb;
fb.foo();
कानूनी होगा।
देखें कि C ++ में "const" के कितने और कौन से उपयोग हैं? अधिक जानकारी के लिए।
const
क्वालीफायर साधन तरीकों में से किसी भी मूल्य पर कहा जा सकता है कि foobar
। अंतर तब आता है जब आप एक कांस्टेबल ऑब्जेक्ट पर एक गैर-कॉन्स्टेंस विधि को कॉल करने पर विचार करते हैं। विचार करें कि क्या आपके foobar
प्रकार में निम्नलिखित अतिरिक्त विधि घोषणा थी:
class foobar {
...
const char* bar();
}
विधि bar()
गैर-कास्ट है और इसे केवल गैर-कॉस्ट मानों से एक्सेस किया जा सकता है।
void func1(const foobar& fb1, foobar& fb2) {
const char* v1 = fb1.bar(); // won't compile
const char* v2 = fb2.bar(); // works
}
const
हालाँकि इसके पीछे का विचार उन तरीकों को चिह्नित करना है जो कक्षा की आंतरिक स्थिति को नहीं बदलेंगे। यह एक शक्तिशाली अवधारणा है लेकिन वास्तव में C ++ में लागू नहीं है। यह एक गारंटी से अधिक एक वादा है। और एक जो अक्सर टूट जाता है और आसानी से टूट जाता है।
foobar& fbNonConst = const_cast<foobar&>(fb1);
const
यद्यपि उन तरीकों को चिह्नित करना है जो वर्ग की आंतरिक स्थिति को बदल नहीं देंगे " के लिए धन्यवाद । यह वास्तव में मैं क्या देख रहा था।
const
?
इन कॉन्स्ट का मतलब है कि कंपाइलर एरर होगा अगर 'कॉन्स्ट के साथ' मेथड आंतरिक डेटा को बदल देता है।
class A
{
public:
A():member_()
{
}
int hashGetter() const
{
state_ = 1;
return member_;
}
int goodGetter() const
{
return member_;
}
int getter() const
{
//member_ = 2; // error
return member_;
}
int badGetter()
{
return member_;
}
private:
mutable int state_;
int member_;
};
कसौटी
int main()
{
const A a1;
a1.badGetter(); // doesn't work
a1.goodGetter(); // works
a1.hashGetter(); // works
A a2;
a2.badGetter(); // works
a2.goodGetter(); // works
a2.hashGetter(); // works
}
अधिक जानकारी के लिए इसे पढ़ें
const
सदस्य कार्यों कि उल्लेख नहीं है परिवर्तनशील सबसे अच्छे रूप में अधूरा है।
ब्लेयर का जवाब निशान पर है।
हालांकि ध्यान दें कि एक mutable
क्वालीफायर है जो एक वर्ग के डेटा सदस्यों में जोड़ा जा सकता है। चिह्नित किए गए किसी भी सदस्य को अनुबंध का उल्लंघन किए बिना एक विधि में संशोधित किया जा सकता है ।const
const
आप इसका उपयोग कर सकते हैं (उदाहरण के लिए) यदि आप किसी ऑब्जेक्ट को यह याद रखना चाहते हैं कि किसी विशेष विधि को कितनी बार कहा जाता है, तो उस पद्धति के "तार्किक" कब्ज को प्रभावित नहीं करता है।
C ++ सामान्य ज्ञान में एक कॉन्स्टेबल मेंबर फंक्शन का अर्थ : आवश्यक इंटरमीडिएट प्रोग्रामिंग स्पष्ट विवरण देता है:
एक कक्षा X के गैर-सदस्य सदस्य फ़ंक्शन में इस सूचक का प्रकार X * const है। यही है, यह एक गैर-स्थिर एक्स के लिए एक निरंतर सूचक है (कॉन्स्ट पॉइंटर्स और पॉइंटर्स टू कॉन्स्ट [7, 21] देखें)। क्योंकि जिस वस्तु को यह संदर्भित करता है वह कब्ज नहीं है, इसे संशोधित किया जा सकता है। एक कक्षा X के एक सदस्य सदस्य कार्य में इसका प्रकार है const X * const। यही कारण है कि, यह एक स्थिर X के लिए एक निरंतर सूचक है। क्योंकि जिस वस्तु को यह संदर्भित करता है वह कास्ट है, इसे संशोधित नहीं किया जा सकता है। यह कांस्ट और नॉन-कास्ट सदस्य कार्यों के बीच अंतर है।
तो आपके कोड में:
class foobar
{
public:
operator int () const;
const char* foo() const;
};
आप इसे इस रूप में सोच सकते हैं:
class foobar
{
public:
operator int (const foobar * const this) const;
const char* foo(const foobar * const this) const;
};
this
नहीं है const
। इसे संशोधित नहीं किया जा सकता है, इसका कारण यह है कि यह एक प्रचलन है।
जब आप const
विधि हस्ताक्षर में उपयोग करते हैं (जैसे आपके कहा const char* foo() const;
:) आप संकलक को बता रहे हैं कि जिस मेमोरी को इंगित this
किया गया है उसे इस विधि (जो foo
यहां है) द्वारा नहीं बदला जा सकता है ।
मैं निम्नलिखित बिंदु जोड़ना चाहूंगा।
आप यह भी कर सकते हैं यह एक const &
औरconst &&
इसलिए,
struct s{
void val1() const {
// *this is const here. Hence this function cannot modify any member of *this
}
void val2() const & {
// *this is const& here
}
void val3() const && {
// The object calling this function should be const rvalue only.
}
void val4() && {
// The object calling this function should be rvalue reference only.
}
};
int main(){
s a;
a.val1(); //okay
a.val2(); //okay
// a.val3() not okay, a is not rvalue will be okay if called like
std::move(a).val3(); // okay, move makes it a rvalue
}
बेझिझक जवाब में सुधार करें। मैं कोई विशेषज्ञ नहीं हूं
*this
सदैव एक अंतराल होता है, भले ही सदस्य कार्य rvalue-ref-योग्य हो और उसे एक अंतराल पर कहा जाता है। उदाहरण है ।
फंक्शन डिक्लेरेशन के साथ उपयोग किया जाने वाला कांस्ट कीवर्ड यह निर्दिष्ट करता है कि यह एक कास्ट मेंबर फंक्शन है और यह ऑब्जेक्ट के डेटा सदस्यों को बदलने में सक्षम नहीं होगा ।
https://isocpp.org/wiki/faq/const-correctness#const-member-fns
"
const
सदस्य फ़ंक्शन" क्या है ?एक सदस्य फ़ंक्शन जो अपनी वस्तु का निरीक्षण करता है (म्यूटेट्स के बजाय)।
सदस्य फ़ंक्शन के पैरामीटर सूची के ठीक बाद एक
const
सदस्य फ़ंक्शन को एकconst
प्रत्यय द्वारा दर्शाया जाता है ।const
प्रत्यय वाले सदस्य कार्यों को "कांस्टेबल सदस्य कार्य" या "निरीक्षक" कहा जाता है। बिनाconst
प्रत्यय के सदस्य कार्यों को "गैर-कास्ट सदस्य कार्य" या "म्यूटेटर" कहा जाता है।class Fred { public: void inspect() const; // This member promises NOT to change *this void mutate(); // This member function might change *this }; void userCode(Fred& changeable, const Fred& unchangeable) { changeable.inspect(); // Okay: doesn't change a changeable object changeable.mutate(); // Okay: changes a changeable object unchangeable.inspect(); // Okay: doesn't change an unchangeable object unchangeable.mutate(); // ERROR: attempt to change unchangeable object }
कॉल करने का प्रयास
unchangeable.mutate()
संकलन समय पर पकड़ा गया त्रुटि है। इसके लिए कोई रनटाइम स्पेस या स्पीड पेनल्टी नहीं हैconst
, और इसे रनटाइम पर जाँचने के लिए आपको टेस्ट-केस लिखने की आवश्यकता नहीं है।सदस्य फ़ंक्शन
const
पर अनुरेखणinspect()
का मतलब यह होना चाहिए कि विधि ऑब्जेक्ट के सार (क्लाइंट-दृश्यमान) स्थिति को नहीं बदलेगी । यह कहने के तरीके से थोड़ा अलग है कि विधि वस्तु की संरचना के "कच्चे बिट्स" को नहीं बदलेगी। C ++ कंपाइलरों को "बिटवाइज़" व्याख्या लेने की अनुमति नहीं दी जाती है जब तक कि वे एलियासिंग समस्या को हल नहीं कर सकते हैं, जिसे सामान्य रूप से हल नहीं किया जा सकता है (अर्थात, एक गैर-कॉन्स्टेंस उपनाम मौजूद हो सकता है जो ऑब्जेक्ट की स्थिति को संशोधित कर सकता है)। इस एलियासिंग मुद्दे से एक और (महत्वपूर्ण) अंतर्दृष्टि: एक सूचक को एक संकेत के साथ एक ऑब्जेक्ट पर इंगित करना इस बात की गारंटी नहीं देता है कि वस्तु नहीं बदलेगी; यह केवल वादा करता है कि वस्तु उस सूचक के माध्यम से नहीं बदलेगी ।