अभिव्यक्ति में वर्ग प्रकार होना चाहिए


82

मैंने कुछ समय के लिए सी ++ में कोड नहीं किया है और जब मैं इस सरल स्निपेट को संकलित करने की कोशिश कर रहा था तो मैं अटक गया:

class A
{
  public:
    void f() {}
};

int main()
{
  {
    A a;
    a.f(); // works fine
  }

  {
    A *a = new A();
    a.f(); // this doesn't
  }
}

2
लाइन जो कहती है "यह नहीं है" वास्तव में ठीक है, जिससे आपका प्रश्न भ्रामक लगता है।
जुआनकोपनज़ा

जवाबों:


166

यह एक सूचक है, इसलिए इसके बजाय प्रयास करें:

a->f();

मूल रूप से ऑपरेटर .(ऑब्जेक्ट के फ़ील्ड और विधियों तक पहुंचने के लिए उपयोग किया जाता है) का उपयोग ऑब्जेक्ट्स और संदर्भों पर किया जाता है, इसलिए:

A a;
a.f();
A& ref = a;
ref.f();

यदि आपके पास एक पॉइंटर प्रकार है, तो आपको एक संदर्भ प्राप्त करने के लिए पहले इसे रोकना होगा:

A* ptr = new A();
(*ptr).f();
ptr->f();

a->bअंकन आम तौर पर सिर्फ एक के लिए आशुलिपि है (*a).b

स्मार्ट पॉइंटर्स पर एक नोट

operator->अतिभारित किया जा सकता है, जो विशेष रूप से स्मार्ट संकेत द्वारा किया जाता है। जब आप स्मार्ट पॉइंटर्स का उपयोग कर रहे होते हैं , तब आप ->पॉइंटेड ऑब्जेक्ट को संदर्भित करने के लिए भी उपयोग करते हैं:

auto ptr = make_unique<A>();
ptr->f();

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

13

एक विश्लेषण की अनुमति दें।

#include <iostream>   // not #include "iostream"
using namespace std;  // in this case okay, but never do that in header files

class A
{
 public:
  void f() { cout<<"f()\n"; }
};

int main()
{
 /*
 // A a; //this works
 A *a = new A(); //this doesn't
 a.f(); // "f has not been declared"
 */ // below


 // system("pause");  <-- Don't do this. It is non-portable code. I guess your 
 //                       teacher told you this?
 //                       Better: In your IDE there is prolly an option somewhere
 //                               to not close the terminal/console-window.
 //                       If you compile on a CLI, it is not needed at all.
}

एक सामान्य सलाह के रूप में:

0) Prefer automatic variables
  int a;
  MyClass myInstance;
  std::vector<int> myIntVector;

1) If you need data sharing on big objects down 
   the call hierarchy, prefer references:

  void foo (std::vector<int> const &input) {...}
  void bar () { 
       std::vector<int> something;
       ...
       foo (something);
  }


2) If you need data sharing up the call hierarchy, prefer smart-pointers
   that automatically manage deletion and reference counting.

3) If you need an array, use std::vector<> instead in most cases.
   std::vector<> is ought to be the one default container.

4) I've yet to find a good reason for blank pointers.

   -> Hard to get right exception safe

       class Foo {
           Foo () : a(new int[512]), b(new int[512]) {}
           ~Foo() {
               delete [] b;
               delete [] a;
           }
       };

       -> if the second new[] fails, Foo leaks memory, because the
          destructor is never called. Avoid this easily by using 
          one of the standard containers, like std::vector, or
          smart-pointers.

अंगूठे के एक नियम के रूप में: यदि आपको अपने दम पर स्मृति का प्रबंधन करने की आवश्यकता है, तो आम तौर पर एक सुपरियर प्रबंधक या पहले से ही उपलब्ध विकल्प है, जो कि आरएआईआई सिद्धांत का पालन करता है।


9

सारांश : इसके बजाय a.f();होना चाहिएa->f();

मुख्य में आपने ए के ऑब्जेक्ट के लिए एक पॉइंटर के रूप में परिभाषित किया है , इसलिए आप ऑपरेटर का उपयोग करके कार्यों तक पहुंच सकते हैं । ->

एक वैकल्पिक , लेकिन कम पठनीय तरीका है(*a).f()

a.f()एफ का उपयोग करने के लिए इस्तेमाल किया जा सकता है (), अगर एक के रूप में घोषित किया गया था: A a;


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