-2

したがって、出力にポインタのアドレスが出力されるというこの問題があります。ポインタがまったく変更されていないため、なぜこれが発生するのかわかりません。

コードは次のとおりです。

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;
}

理由はわかりませんが、次のように表示されます。

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 
4

2 に答える 2

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

};

vi関数が戻ると、、、fuおよびへのポインタveは無効になります。住所が印刷されているのではなく、単にゴミが表示されています。

ただし、デザイン全体でポインターを使用する必要はありません。

于 2012-03-31T03:51:51.433 に答える
0

表示されているのは、関数の正式なパラメーターのアドレスです。本質的に意味のない値であり、役に立たず、基本的にスタック上のランダムな位置へのポインターになります-コンストラクターを呼び出したときにスタックがたまたまあった場所。コンピュータとコンパイラがどのように機能するかについてもっと学ぼうとしない限り、基本的にこれらの値に興味を持つことはありません。

ポインタが何をするのか、いつ適切なのか、そしてそれらの意味を理解することは非常に重要です。

この場合、次の理由でポインタを使用することは適切ではありません。

  • クラス内にデータを保存しようとしています。保存するタイプは次のとおりです。
    • とにかくポインタと同じサイズ(int)
    • クラスの外にそのメモリを保持する理由はありません(とにかく、表示されていません)
    • 必要な場合でも、参照はエラーが発生しにくくなります(int *の代わりにint&)
  • また、スタックが正常に機能する場合は、ヒープを使用してクラスのインスタンスを作成しています。

私はこれがあなたが意図したものだと思います:

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;
    };
};

クラスメンバーのタイプと値を出力するときの両方に*がないことに注意してください。

それほど良くはありませんが、構文的に正しいポインタの使用法は、1回の呼び出し(いずれかのクラスに入れる)でクラス内の複数の値をクエリすることです。

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

たとえば、次のように呼び出されます。

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

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

ここでは、スタック変数vidaとvelocidadのアドレスをポインターとして渡し、fuerzaの値が必要ないため、追加のアドレスを渡すことができた場合にNULLを渡しました。次に、渡されたポインタがnullでない場合は、それらが指すメモリに割り当てます。関数が戻ると、スタック変数はクラスの値を持ちます。

もちろん、実際にこれを行うべきではありません。値を公開するか、値を返すだけの関数を追加することによって、値へのアクセスを別の方法で提供する必要があります。

public:
    int Vida() {
        return vida;
    }

次に、次のことを実行できます。

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

もちろん、ヒープを使用してAndroideインスタンスを作成する理由がない限り、ヒープの代わりにスタックメモリを使用する必要があります。

Androide andro;

それ以外の

Androide *andro = new Androide();
于 2012-03-31T18:05:29.210 に答える