C ++ में किसी वर्ग के सदस्यों को संदर्भित करने के लिए मैं एक डॉट, एरो या डबल कोलन का उपयोग कब करता हूं?


243

: अन्य सी व्युत्पन्न भाषाओं सेल्सियस के लिए (जावा या सी #) की तरह से आ ++, यह पहली बहुत भ्रामक है कि सी ++ तीन तरीके एक वर्ग के सदस्यों का उल्लेख करने के लिए किया है a::b, a.bऔर a->b। मैं इनमें से किस ऑपरेटर का उपयोग करता हूं?

(नोट: यह स्टैक ओवरफ्लो के C ++ FAQ के लिए एक प्रविष्टि माना जाता है । यदि आप इस रूप में FAQ प्रदान करने के विचार की आलोचना करना चाहते हैं, तो मेटा पर पोस्टिंग जो यह सब शुरू करती है वह करने के लिए जगह होगी। उत्तर) उस प्रश्न की निगरानी C ++ चैटरूम में की जाती है , जहाँ पहली बार में FAQ विचार शुरू हुआ है, इसलिए आपका उत्तर उन लोगों द्वारा पढ़े जाने की संभावना है, जो विचार के साथ आए थे।)

जवाबों:


248

तीन अलग-अलग ऑपरेटर सी ++ एक वर्ग या वर्ग ऑब्जेक्ट के सदस्यों तक पहुंचने के लिए उपयोग करते हैं, अर्थात् डबल कोलन ::, डॉट .और एरो ->, तीन अलग-अलग परिदृश्यों के लिए उपयोग किए जाते हैं जो हमेशा अच्छी तरह से परिभाषित होते हैं। यह जानने के बाद आप तुरंत के बारे में काफी एक बहुत कुछ पता करने के लिए अनुमति देता है aऔर bबस को देखकर a::b, a.bया a->bक्रमशः, अपने आप को देखो किसी भी कोड में।

  1. a::bकेवल तभी उपयोग किया जाता है यदि bवर्ग (या नाम स्थान) का सदस्य है a। यही है, इस मामले aमें हमेशा एक वर्ग (या नाम स्थान) का नाम होगा।

  2. a.bका उपयोग केवल तभी किया जाता है जब bवस्तु का सदस्य (या किसी वस्तु का संदर्भ) हो a। तो a.b, aहमेशा एक वर्ग के लिए एक वास्तविक वस्तु (या किसी वस्तु का संदर्भ) होगा।

  3. a->bमूल रूप से, एक आशुलिपि संकेतन है (*a).b। हालाँकि, ->केवल सदस्य अभिगम संचालकों का ही अधिभार हो सकता है, इसलिए यदि aकिसी वर्ग की ऐसी वस्तु है जो अतिभारित होती है operator->(सामान्य इस प्रकार के स्मार्ट पॉइंटर्स और पुनरावृत्तियाँ हैं), तो इसका अर्थ है कि जो भी क्लास डिज़ाइनर ने लागू किया है। निष्कर्ष निकालने के लिए: a->bयदि a, एक पॉइंटर है, bतो पॉइंटर को aसंदर्भित ऑब्जेक्ट का सदस्य होगा । यदि, हालाँकि, aकिसी वर्ग की एक वस्तु है जो इस ऑपरेटर को अधिभारित करती है, तो ओवरलोड ऑपरेटर फ़ंक्शन operator->()को लागू किया जाता है।


छोटा प्रिंट:

  • C ++ में, प्रकार के रूप में घोषित class, structया union"वर्ग प्रकार का" माना जाता है। तो उपरोक्त तीनों को संदर्भित करता है।
  • संदर्भ हैं, शब्दार्थ, वस्तुओं के लिए उपनाम, इसलिए मुझे "# 3 के साथ" एक पॉइंटर के लिए "या संदर्भ जोड़ना चाहिए"। हालाँकि, मैंने सोचा कि यह सहायक से अधिक भ्रामक होगा, क्योंकि संकेत ( T*&) का संदर्भ शायद ही कभी उपयोग किया जाता है।
  • डॉट और एरो ऑपरेटरों का उपयोग किसी ऑब्जेक्ट से स्थिर वर्ग के सदस्यों को संदर्भित करने के लिए किया जा सकता है, भले ही वे ऑब्जेक्ट के सदस्य न हों। (यह इंगित करने के लिए ओली का धन्यवाद!)

10
संभवतः यह है कि स्पष्ट किया जाना चाहिए .और ->यह भी एक वस्तु के माध्यम से पहुंच वर्ग स्टैटिक्स के लिए इस्तेमाल किया जा सकता है, भले ही वे सख्ती से "वस्तु के सदस्यों" नहीं कर रहे हैं।
ओलिवर चार्ल्सवर्थ

@ ओली: यह वास्तव में सच है। मैंने इसे छोटे प्रिंट में जोड़ दिया है, क्योंकि मुझे लगता है कि यह मुख्य और सामान्य नहीं है कि मुख्य पाठ में सूचीबद्ध किया जाए।
sbi

3
पूर्णता के लिए, यह इंगित करने के लायक हो सकता है कि operator*()अतिभारित भी किया जा सकता है, और यह कि कुछ भी नहीं है जो अधिभार के अनुरूप है operator->()! (मैंने BTW को कम नहीं किया, बस डुप्लिकेट के एक लंबे अनुक्रम के माध्यम से यहां आया)
जुआनकोपंजा

@OliCharlesworth आपको पता होगा कि C ++ मानक में कहां निर्दिष्ट है?
सूअर

1
@juanchopanza: आपको ->ओवरलोडिंग operator*और उपयोग करके ., हालांकि, का जंजीर व्यवहार नहीं मिल सकता है । केवल operator->ओवरलोड ही मिलता है।
बेन वोइग्ट

36

Sbi के बिंदु 3 के लिए एक विकल्प का सुझाव देना

a->bकेवल तभी उपयोग किया जाता है जब aकोई सूचक हो। यह उस वस्तु (*a).bके bसदस्य के लिए एक आशुलिपि है , जो aइंगित करता है। C ++ में दो प्रकार के पॉइंटर्स हैं, "रेगुलर" और स्मार्ट पॉइंटर्स। इस तरह के नियमित संकेत के लिए A* a, संकलक लागू करता है ->। जैसे स्मार्ट पॉइंटर्स के लिए std::shared_ptr<A> a, ->कक्षा का एक सदस्य कार्य है shared_ptr

Rationale: इस FAQ के लक्षित दर्शक स्मार्ट पॉइंटर्स नहीं लिख रहे हैं। उन्हें यह जानने की आवश्यकता नहीं है कि ->वास्तव में कहा जाता है operator->(), या यह एकमात्र सदस्य अभिगम विधि है जिसे अतिभारित किया जा सकता है।


4
इससे कोई फर्क नहीं पड़ता कि मैं इससे सहमत हूं या नहीं, मैं इसे +1एक वैकल्पिक उत्तर प्रदान करने के लिए देता हूं ।
sbi

2
ठीक है, निष्पक्ष होने के ->लिए भी मानक iterators जो किसी भी सी ++ प्रोग्रामर को जल्द ही मिलना चाहिए, के लिए अतिभारित है, इसलिए यह कहना कि यह केवल संकेत के लिए उपयोग किया जा सकता है भ्रामक हो सकता है।
किस्किरके

@ किस्किरके "साधारण सी ++ प्रोग्रामर" को स्मार्ट पॉइंटर या इटरेटर प्रकार लिखने की आवश्यकता नहीं है , बस उनका उपयोग करना। "पॉइंटर की तरह डीरेफरेंस" दोनों पर लागू होता है।
कैलेथ सेप

0
#include <iostream>
#include <string>

using namespace std;

class Human {
private:
    int age;

public:
    string name;

    Human(int humanAge, string humanName) 
         : age(humanAge), name(std::move(humanName)) {}

    void DoSomething() {
        cout << age << endl;
    }

    static void DisplayAge(const Human& person) {
        cout << person.age << endl;
    }

    // ...
};

int main() {
    // Usage of Dot(.) 
    Human firstMan(13, "Jim"); // firstMan is an instance of class Human
    cout << firstMan.name << endl; // accessing member attributes
    firstMan.DoSomething(); // accessing member functions

    // Usage of Pointer Operator (->)
    Human* secondMan = new Human(24, "Tom");
    cout << secondMan->name << endl; // accessing member attributes
    secondMan->DoSomething(); // accessing member functions
    cout << (*secondMan).name << endl; // accessing member attributes
    (*secondMan).DoSomething(); // accessing member functions

    // Usage of Double Colon (::)
    Human::DisplayAge(firstMan);
    firstMan.DisplayAge(firstMan); // ok but not recommended
    secondMan->DisplayAge(firstMan); // ok but not recommended

    delete(secondMan);

    return 0;
}

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


@ sbi so grumpy हा, मुझे पता है कि यह किसी प्रकार की पुनरावृत्ति है। मैं सिर्फ एक स्पष्ट उदाहरण देना चाहता हूं कि उन्हें कैसे उपयोग करना है। और जहां मैंने कहा कि ->केवल एक पॉइंटर द्वारा उपयोग किया जा सकता है जो कि द्वारा ढेर पर आवंटित किया गया है new? नीचे, दूसरा आइटम, मुझे लगता है कि मैं वास्तव में यह स्पष्ट करता हूं कि ->सूचक के लिए है। और इससे पहले कि आप नीचे जाएं, आप className::non_static_member_function()अपने आप से c ++ 14 के साथ बेहतर प्रयास करें। संदर्भ एक सूचक नहीं है, इसलिए यह उपयोग कर सकता है ., और मैं अपने उत्तर में इसे और अधिक स्पष्ट कर दूंगा।
हू जिक्सी

0

डॉट ऑपरेटर का उपयोग प्रत्यक्ष सदस्य चयन परिदृश्यों में किया जाता है।

print(a.b)

यहां, हम पहुंच बना रहे हैं b, जो किसी वस्तु का प्रत्यक्ष सदस्य है a। तो, मुख्य रूप से, aएक वस्तु है और bएक सदस्य (फ़ंक्शन / चर आदि) है a


एरो ऑपरेटर अप्रत्यक्ष सदस्य चयन परिदृश्यों में उपयोग किया जाता है।

print(a->b)

यहाँ, हम पहुँच रहे हैं bजो कि वस्तु का एक सदस्य है, जिसे इंगित किया गया है a। यह (*a).bयहाँ और इसलिए शॉर्टहैंड है, aमुख्य रूप से किसी ऑब्जेक्ट का पॉइंटर है और bउस ऑब्जेक्ट का सदस्य है।


डबल कोलोन (स्कोप) ऑपरेटर का उपयोग नाम स्थान से संबंधित प्रत्यक्ष सदस्य चयन परिदृश्यों में किया जाता है।

print(a::b)

यहाँ, हम पहुँच रहे हैं bजो वर्ग / नाम स्थान का एक सदस्य है। aमुख्य रूप से, aएक वर्ग / नाम स्थान है और bएक सदस्य (फ़ंक्शन / चर आदि) है a

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