-2

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 
Matt
  • 22,721
  • 17
  • 71
  • 112
  • 1
    Please write standard English. I do not refer to the Spanish in your code, but to the seemingly purposely sloppy English with which you describe and ask about your code. – thb Mar 31 '12 at 03:53
  • 2
    I suggest you read a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). You seem to be applying a Java mindset to C++ which is a very bad way to go about it. – Pubby Mar 31 '12 at 03:54
  • Yeah actually last semester I was using java :P, and sorry for the spanish stuff... I was too lazy to edit everything =/. Anyways thanks to both of you! – Alejandro Gonzalez Mar 31 '12 at 04:00
  • 2
    Please avoid using pseudo-words like `cuz` or smiley faces, because, with this language, you cannot be taken seriously. – npclaudiu Mar 31 '12 at 18:20

2 Answers2

3
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.

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • oh, I was using them cuz our teacher said we had to learn how to use them in pretty much everything we do. K, so no pointers needed. Thanks! – Alejandro Gonzalez Mar 31 '12 at 03:55
  • Dude btw what did you do to post the code like well-formatted? I'm new here =/ – Alejandro Gonzalez Mar 31 '12 at 03:56
  • @AlejandroGonzalez Your teacher is misinformed - correct C++ involves very little use of pointers. To format code, select the text and press the `[{}]`button. You can also indent it 4 columns to achieve the same effect. Welcome to the site! – Pubby Mar 31 '12 at 03:57
  • Furthermore, its always best practice to use *references* over pointers when possible. – Alex Z Mar 31 '12 at 04:01
  • So, I changed it to normal integers and used AndroideDec->setvalores(vida*2,fuerza*2,velocidad*2); but it prints 0, 0, 0. Any idea why? – Alejandro Gonzalez Mar 31 '12 at 04:03
  • @AlejandroGonzalez Not sure, but here's some working code to get you started: http://ideone.com/o7xZL – Pubby Mar 31 '12 at 04:08
  • Oh thanks! Will try to use it. The mess in my first code is cuz it's supposed to be an example of a decorator. – Alejandro Gonzalez Mar 31 '12 at 04:14
  • @AlejandroGonzalez: BTW Your professor may mean that he wants you to use pointer in this exercise in order to understand them. That's different from suggesting that this is a good application of pointer in C++ (which it isn't). – dmckee --- ex-moderator kitten Mar 31 '12 at 16:48
0

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();
fcrick
  • 484
  • 5
  • 12