简体   繁体   中英

C++ Pointers In A Game

I am in what seems to be a never ending quest to understand pointers. I finally have a working code using pointers to create a quick character and enemy, then mock an overly simple battle. It works 100% as it seems, but I'm not 100% sure it's correct or what I did to make it right. I have read 13 chapters so far in my C++ book (2 being over pointers specifically), but I'm still not sure it's clicked. If this looks like a valid use and proper utilization of them, I think I'm getting there, just wanted some clarification if it is. Thanks in advance!

#include <iostream>
#include <string>

#ifndef CLASS_H
#define CLASS_H

class Unit
{
public:
    Unit(const std::string name, int hp, int power);
    ~Unit();

    void    printHP();
    void    attack(Unit* unit);
    bool    isDead();

private:
    std::string     mName;
    int             mHP;
    int             mPower;

};

Unit::Unit(const std::string name, int hp, int power)
{
    mName   = name;
    mHP     = hp;
    mPower  = power;
}
void Unit::printHP()
{
    std::cout << std::endl;
    std::cout << mName << "'s HP: " << mHP << std::endl;
}
void Unit::attack(Unit* unit)
{
    std::cout << std::endl;
    std::cout << unit->mName << " takes " << this->mPower << " damage! " << std::endl;
    unit->mHP -= this->mPower;
}
bool Unit::isDead()
{
    return this->mHP < 1;
}
Unit::~Unit()
{

}
#endif

int main()
{
    Unit player1("GoodFellow", 20, 5);
    Unit Enemy("ABadMan", 10, 2);

    while (!Enemy.isDead())
    {
        player1.printHP();
        Enemy.printHP();

        player1.attack(&Enemy);
        Enemy.attack(&player1);
    }
}

Modified it to this... I think I get the reason for only using a reference, just trying to get the concept of pointers....

#include <iostream>
#include <string>

#ifndef CLASS_H
#define CLASS_H

class Unit
{
public:
    Unit(const std::string name, int hp, int power);
    ~Unit();

    void    printHP();
    void    attack(Unit& unit);
    bool    isDead();

    void    setHP(int hp);

private:
    std::string     mName;
    int             mHP;
    int             mPower;

};

Unit::Unit(const std::string name, int hp, int power)
{
    mName   = name;
    mHP     = hp;
    mPower  = power;
}
void Unit::printHP()
{
    std::cout << std::endl;
    std::cout << mName << "'s HP: " << mHP << std::endl;
}
void Unit::attack(Unit& unit)
{
    std::cout << std::endl;
    std::cout << unit.mName << " takes " << this->mPower << " damage! " << std::endl;
    unit.mHP -= this->mPower;
}
bool Unit::isDead()
{
    return this->mHP < 1;
}
void Unit::setHP(int hp)
{
    this->mHP = hp;
}
Unit::~Unit()
{

}
#endif

int main()
{
    Unit player1("GoodFellow", 20, 5);
    Unit Enemy("ABadMan", 10, 2);

    while (true)
    {
        while (!Enemy.isDead())
        {
            player1.printHP();
            Enemy.printHP();

            player1.attack(Enemy);
            Enemy.attack(player1);
        }

        char playAgain;
        std::cout << "Fight again? (y)/(n)" << std::endl;
        std::cin >> playAgain;

        if (playAgain == 'n')
        {
            break;
        }
        else
        {
            Enemy.setHP(10);
        }

    }
}

Yes, that's a reasonable use of pointers. I was actually glad to see that you used them very little. I was half expecting to see Unit* player1 = new Unit ... and such all over the place. But no, you used automatic storage duration all over (rather than dynamic), which was very appropriate.

So the main reason for passing Unit* s to the attack functions is to that inside the function you can modify the Unit that you're attacking and have the effect seen outside. If you were to pass the Unit s directly, they would be copied into the function and then the unit->mHP -= this->mPower; would only affect the copy.

However, there is a more appropriate tool at your disposal here. You can use references . A reference also allows you to pass an object without copying it, so that modifications inside the function can be seen outside. Your attack function signature would change to:

void Unit::attack(Unit& unit)

The type Unit& is a "reference to Unit ". Don't confuse the use of & with taking the address of an object - it means something completely different here. You would then call it like so:

player1.attack(Enemy);

The point is you should try to avoid pointers as much as possible. Since you can use references here, which are safer (you do not need to check for null ), you should use them.

It's fine to learn about how pointers to work, but in doing so, you should learn how to use other more appropriate tools for the job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM