-1

I am trying to build a dynamic array of objects using pointers arithmetic. However, the compiler return the following error in this line in the main.cpp

(*(lista+n))(id1,seleccion1,edad1,camiseta1);


error: no match for call to '(jugador) (int &, int & short, short int &, short int &)' 

any suggestion is welcome, thanks.

This is the class.

class jugador
{
private:

    int id;
    short seleccion;
    short edad;
    short camiseta;

public:
    jugador();
    jugador(int ID, short SELECCION, short EDAD, short CAMISETA);
    int obtener_id();
    short obtener_seleccion();
    short obtener_edad();
    short obtener_camiseta();
    void cambiar_id(int nueva_id);
    void cambiar_seleccion(short nueva_seleccion);
    void cambiar_edad(short nueva_edad);
    void cambiar_camiseta(short nueva_edad);
    void cambiar_todo(int nueva_ID, short nueva_SELECCION, short nueva_EDAD, short nueva_CAMISETA);
    void mostrar_jugador();
};

The constructors...

jugador::jugador()
{

    id=999999;
    seleccion=32;
    edad=99;
    camiseta=99;

}

jugador::jugador(int ID, short SELECCION, short EDAD, short CAMISETA)
{

    id=ID;
    seleccion=SELECCION;
    edad=EDAD;
    camiseta=CAMISETA;

}

Here is the full code.

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
  • 2
    From the looks `(*(lista+n))(id1,seleccion1,edad1,camiseta1);` seems like a creepy misconception of a function pointer. But since you are deferencing it then the compiler looks for an object. We need to know your intention. Could you show us the main? Or the concrete part? – Claudiordgz Mar 20 '14 at 17:31
  • 3
    You haven’t shown us the code which causes the error. Please post an [SSCCE](http://www.sscce.org/). – Konrad Rudolph Mar 20 '14 at 17:32
  • Where exactly do you have anything in your code with the name `player`? – barak manos Mar 20 '14 at 17:33
  • Rather than running a translator over the error message, you should run the compiler with language settings set to English. – ecatmur Mar 20 '14 at 17:34
  • Is `lista` an array of `jugador` objects? – 001 Mar 20 '14 at 17:34
  • Looks like, yes ... @JohnnyMopp (http://www.spanishcentral.com/translate/jugador) – alk Mar 20 '14 at 17:38
  • Here is the full code http://pastebin.com/DsJiNGRi – user3443151 Mar 20 '14 at 17:43
  • @ecatmur I just did that =) – user3443151 Mar 20 '14 at 17:46
  • The whole problem is that you are allocating the memory with realloc and then you are trying to call explicitly the constructor. That's a bad idea for several reasons. May I ask why are you trying to do? – Pedrom Mar 20 '14 at 17:58
  • I use realloc because in the problem the numbers of "jugadores" is not given. So I have to request for memory every time I need it.An what I want is to construct an array of "jugadores" but w/o knowing the number of elements. – user3443151 Mar 20 '14 at 18:00
  • You don't need relloc for that.. just doing new jugadores[n] would be enough. Note that "new" does more than just allocating the memory, it also calls the constructor and set the vtables up. – Pedrom Mar 20 '14 at 18:31

2 Answers2

1

Is there a special reason you are not using std::vector<jugador> Check this thread for the advantages of replacing realloc with vector

You have not given enough information so here is what I can tell from the looks of the error:

(*(lista+n))(id1,seleccion1,edad1,camiseta1);

that is NOT a function pointer, it's not even pointing to a function in the first place.

It seems like you are trying to construct an array of jugador by moving the lista pointer. If that is what you want to do then you can do late initialization.

jugador * lista;  //< unitialized pointer
int n = 11; //< your number of players, lets suppose 11
lista = new jugador[11]; // now you have an array of jugadores
for(int i = 0; i != n; ++i)
{
  lista[i] = jugador(id1,seleccion1,edad1,camiseta1); 
}
// use your jugadores, let's suppose you want to use the tenth jugador
jugador *iterator = lista;
iterator+10;
use(*iterator); //*iterator variable holds your 10th jugador object
delete[] lista;

You are using realloc in your code, I suggest you try new and delete instead. Or else provide an explanation of why using realloc is a good choice.

Another thing I noticed in your code is that you don't free the memory you are using. Thus you have a memory leak.

If you need more jugador the use std::copy to achieve that

// let's say in this point you need 20 jugador more
jugador * newlista = new jugador[n+20];
std::copy(lista, lista+11, newlista);
delete[] lista;  //you delete the old buffer
for(int i = 11; i != n+20; ++i)
{
  newlista[i] = jugador(id1,seleccion1,edad1,camiseta1); 
}
// and now newlista has your jugadores, you can even make a function that does that
delete[] newlista ; // delete your jugadores
Community
  • 1
  • 1
Claudiordgz
  • 3,023
  • 1
  • 21
  • 48
  • I already understood your problem, and by that explanation `realloc` is a bad choice, you should use `new` and `delete`, if you need further `jugador` objects then allocate more memory. You can even allocate 100 `jugador` and only use 10. `realloc` is a c function which you are combining with objects from `c++`. The fact that it is named `new` does not mean you can't change it dynamically. – Claudiordgz Mar 20 '14 at 18:01
  • 1
    You still have problems with the line lista = new jugador[11] since it is calling the implicit constructor in that moment. I am agree that the version using vectors is superior, but if he still wants to use an array then he must have an array of pointers instead – Pedrom Mar 20 '14 at 18:53
  • I read what you said... but all I could read was "You want pointer arithmetic? I'LL GIVE YOU POINTER ARITHMETIC!" but yes, that way you wouldn't call the default constructor and you wouldn't create copies. +1 – Claudiordgz Mar 20 '14 at 19:12
  • @Claudiordgz That's right, I don't see for example how to point to the constructor function with reallocate. With Your suggestion I could solve the problem easily. After it I understood a little more about reallocate and could make a working code with it, but I don't see the way to call the constructor. – user3443151 Mar 20 '14 at 23:35
  • @user3443151 Es lo mismo, tendrías que realocar la memoria utilizando realloc para después en un `for` llamar el constructor. La única manera de llamar el constructor desde la alocación de memoria es con la sugerencia de `Pedrom` de utilizar un arreglo de apuntadores a apuntadores. – Claudiordgz Mar 20 '14 at 23:55
1

I am completely agreed with Claudiordgz's response. However, if you want to call the constructor with parameters (without making extra copies) you will need to make an array of pointers instead of an array of objects. I am pasting a version of your code with that. However, I still think that a version using vectors is safer and superior.

Code:

int main()
{
    int id1;
    short seleccion1, edad1, camiseta1;
    jugador arreglo[5];
    int n = 0, i;
    char opcion = 's';
    jugador **lista=NULL;

    while (opcion == 's')
    {
        lista = new jugador*[n];
        cout<<"id: "<<endl;
        cin>>id1;
        cout<<"Seleccion: "<<endl;
        cin>>seleccion1;
        cout<<"Edad: "<<endl;
        cin>>edad1;
        cout<<"Camiseta: "<<endl;
        cin>>camiseta1;


        lista[n] = new jugador(id1,seleccion1,edad1,camiseta1);
        n++;
        cout << "Desea ingresar otro elemento? (s/n): ";
        cin >> opcion;
    }
    cout << "\nArreglo completo\n";
    for (i=0; i<n; i++)
    {
        lista[n].mostrar_jugador();
    }

    //deallocating memory

    for (int i=0; i<n; i++)
    {
            delete jugador[i];
    }

    delete [] jugador;

    return 0; 
}
Pedrom
  • 3,823
  • 23
  • 26