La expresión debe tener un tipo de clase

3 minutos de lectura

avatar de usuario
adrianton3

No he codificado en C++ durante algún tiempo y me quedé atascado cuando intenté compilar este fragmento simple:

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

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

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

  • la línea que dice “esto no lo hace” en realidad está bien, lo que hace que su pregunta parezca confusa.

    – juanchopanza

    1 de julio de 2011 a las 11:58

avatar de usuario
Cos

Es un puntero, así que en su lugar intente:

a->f();

Básicamente el operador . (usado para acceder a los campos y métodos de un objeto) se usa en objetos y referencias, por lo que:

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

Si tiene un tipo de puntero, primero debe desreferenciarlo para obtener una referencia:

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

los a->b notación suele ser sólo una abreviatura de (*a).b.

Una nota sobre los punteros inteligentes

los operator-> se puede sobrecargar, lo que es especialmente utilizado por los punteros inteligentes. Cuando usa punteros inteligentes, también usa -> para referirse al objeto señalado:

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

  • Recién comenzando con C ++, todavía tengo que convertirlo en un automatismo para determinar si usar un puntero o una referencia. En mi caso particular, todo lo que necesitaba era una referencia, pero por alguna razón pasé un puntero en su lugar. De todos modos, gracias por la clara explicación!

    – Guillermo M.

    25/07/2016 a las 20:52


Permitir un análisis.

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

Como consejo general:

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.

Como regla general: si necesita administrar la memoria por su cuenta, generalmente ya hay un administrador superior o una alternativa disponible, una que sigue el principio RAII.

avatar de usuario
Ozair Kafray

Resumen: En vez de a.f(); debería ser a->f();

En main has definido a como un puntero a objeto de Apara que pueda acceder a las funciones usando el -> operador.

Un alternopero la forma menos legible es (*a).f()

a.f() se podría haber usado para acceder a f(), si a fue declarado como:
A a;

a es un puntero. necesitas usar->no .

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad