Question

So I have this problem where the output prints the address of my pointer, I have no idea why this happens cuz the pointers is not modified at all

Heres the code:

using namespace std;

class AndroideAbstracto {
protected:
    int *vida;
    int *fuerza;
    int *velocidad;
public:

    void setvalores(int vi, int fu, int ve) {
        velocidad = &ve;
        vida = &vi;
        fuerza = &fu;

    };
    virtual void imprimir(void) = 0;
};

class Androide : public AndroideAbstracto {
public:

    void imprimir() {
        std::cout << "Caracteristicas del androide:" << endl;
        cout << "Velocidad = " << *velocidad << endl;
        cout << "Vida = " << *vida << endl;
        cout << "Fuerza = " << *fuerza << endl;

    };

};

class Decorator : public AndroideAbstracto {
protected:
    AndroideAbstracto *AndroideDec;
public:

    Decorator(AndroideAbstracto* android_abs) {
        AndroideDec = android_abs;
    }
    virtual void imprimir(void) = 0;
};

class Androide_Con_Habi : public Decorator {
protected:
    string habilidad;
public:

    Androide_Con_Habi(AndroideAbstracto* android_abs, string habi) : Decorator(android_abs) {
        habilidad = habi;
    }

    virtual void imprimir() {
        AndroideDec->imprimir();
        cout << "La habilidad especial del androide es: " << habilidad << endl;
    }
};

class Androide_Elegido : public Decorator {
protected:
    bool elegido;
public:

    Androide_Elegido(AndroideAbstracto *android_abs, bool es) : Decorator(android_abs) {
        elegido = es;
    }

    virtual void imprimir() {
        if (elegido) {
            //            *vida =(*vida) * 2;  //Im quite new to C++ so im not really
            //            *fuerza *=2;         //sure how should I multiply these pointers
            //            *velocidad *=2;
            //            AndroideDec->setvalores(vida*2,fuerza*2,velocidad*2);
            AndroideDec->imprimir();
            cout << "Este androide es uno de los elegidos";
        }
    }
};

int main(int argc, char *argv[]) {

    Androide *andro = new Androide();
    andro->setvalores(600, 700, 300);
    andro->imprimir();
    Androide_Con_Habi *andro_con_habi = new Androide_Con_Habi(andro, "Volar");
    andro_con_habi->imprimir();

    Androide_Elegido *superpoderoso = new Androide_Elegido(andro, true);
    superpoderoso->imprimir();

    delete superpoderoso;
    delete andro;
    delete andro_con_habi;
    return 0;
}

I have no idea why but this prints:

Caracteristicas del androide:
Velocidad = 300
Vida = 600
Fuerza = 700

Caracteristicas del androide:
Velocidad = 300
Vida = 152436744
Fuerza = -1074718788
La habilidad especial del androide es: Volar


Caracteristicas del androide:
Velocidad = 300
Vida = 152436744
Fuerza = 1
Este androide es uno de los elegidos 
Was it helpful?

Solution

void setvalores(int vi, int fu, int ve) {
    velocidad = &ve;
    vida = &vi;
    fuerza = &fu;

};

The pointers to vi, fu, and ve get invalidated when the function returns. You're not seeing addresses being printed, but simply garbage.

Your entire design doesn't and shouldn't need to use pointers though.

OTHER TIPS

What you're seeing is the addresses of the formal parameters of your function. Essentially meaningless values that aren't useful, and will essentially be pointers to a random position on your stack - wherever the stack happened to be when you called the constructor. You would basically never be interested in these values unless you were trying to learn more about how your computer and compiler worked.

It's very important to understand what pointers do and when they're appropriate, and what their implications are.

In this case, it's not suitable to use pointers because:

  • You're trying to store data inside your class, and the type you're storing is:
    • The same size as a pointer anyway (int)
    • There's no reason to keep the memory for it outside your class (none shown, anyway)
    • even if you needed to, references would be less error-prone (int & instead of int *)
  • Also, you're using the heap to make an instance of your class, when the stack will do just fine.

I suspect this is what you intended:

class AndroideAbstracto {
protected:
    int vida;
    int fuerza;
    int velocidad;
public:

    void setvalores(int vi, int fu, int ve) {
        velocidad = ve;
        vida = vi;
        fuerza = fu;

    };
    virtual void imprimir(void) = 0;
};

class Androide : public AndroideAbstracto {
public:
    void imprimir() {
        std::cout << "Caracteristicas del androide:" << endl;
        cout << "Velocidad = " << velocidad << endl;
        cout << "Vida = " << vida << endl;
        cout << "Fuerza = " << fuerza << endl;
    };
};

Note the lack of *'s both in the types of the class members, and when printing out the values.

One not terribly good, but syntactically correct use of pointers here would be to query multiple values in the class with a single call (put in either class):

void getvalores(int *vi, int *fu, int *ve) {
    if (vi)
        *vi = vida;
    if (fu)
        *fu = fuerza;
    if (ve)
        *ve = velocidad;
}

called like this, for example:

int vida, velocidad;
andro->getvalores(&vida, NULL, &velocidad);

cout << "Velocidad = " << velocidad << endl;
cout << "Vida = " << vida << endl;

Here we've passed the address of the stack variables vida and velocidad as pointers, and passed NULL where we could have passed an additional address because we don't want the value of fuerza. We then assign to the memory pointed to by the passed in pointers if they're not null, and when the function returns, the stack variables have the values from the class.

You shouldn't actually do this, of course - you should just provide access to the values another way, either directly by making them public, or by adding functions that just return them.

public:
    int Vida() {
        return vida;
    }

Then you can just do:

cout << "Vida = " << andro->Vida() << endl;

And, of course, unless there is a reason to use the heap to create your Androide instance, you should just use stack memory instead of the heap.

Androide andro;

instead of

Androide *andro = new Androide();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top