2011-07-01 4 views
46

ho have't scritto in C++ per qualche tempo e sono rimasto bloccato quando ho provato a compilare questo semplice frammento diespressione deve avere tipo di classe

#include "iostream" 
using namespace std; 

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" 
system("pause"); 
} 
+0

la riga che dice "questo non funziona" è in realtà OK, rendendo la tua domanda un po 'confusa. – juanchopanza

risposta

105

E 'un puntatore, in modo da cercare invece:

a->f(); 

Fondamentalmente l'operatore . (utilizzato per accedere ai campi e metodi di un oggetto) viene utilizzato su oggetti e riferimenti, così:

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

Se si dispone di un tipo di puntatore, è necessario dereferenziarlo primo a ottenere un riferimento:

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

La notazione a->b di solito è solo una scorciatoia per (*a).b.

+0

L'avvio di C++ deve ancora essere automatizzato per capire se utilizzare un puntatore o un riferimento. Nel mio caso particolare tutto ciò di cui avevo bisogno era un riferimento, ma per qualche motivo ho passato un puntatore. Comunque, grazie per la chiara spiegazione! –

6

Sommario: Invece di a.f(); dovrebbe essere a->f();

Nel principale è stato definito un come un puntatore a oggetto diA, in modo da poter accedere alle funzioni utilizzando l'operatore ->.

a.f() avrebbe potuto essere utilizzato per accedere f(), se un è stato dichiarato come: A a;

4

a è un puntatore. È necessario utilizzare ->, non .

11

Consentire un'analisi.

#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. 
} 

Come consiglio generale:

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. 

Come regola generale: se avete bisogno di gestire la memoria da soli, v'è generalmente un manager superiour o alternativa disponibile già, quella che segue la Principio RAII.