成员函数的可变生命周期,值保持重置为“0”,为什么?

时间:2014-05-30 23:00:46

标签: c++ class member-functions

问题说明

我正在尝试为孩子们编写甲虫游戏的实现。以下代码在我调用函数时将wingslegshead等初始化为零。

初始化应该在哪里,以便我可以增加wingslegshead等,而不会在第二次调用函数时丢失它们的值?


#include <iostream>
#include <ctime>
#include <stdlib.h>

using namespace std;

class Die
{
private:
    int num;

public:
    int roll();
    int getNum();
    void process();
};


int Die::roll() //roll one dice to get random number
{
    srand((unsigned)time(0));
    num=(rand() % 6)+1;
    cout<<num;
}

int Die::getNum()
{
    return num;
}


void Die::process() //player is building the beetel
{
    int eyes=0, antennas=0, legs=0, wings=0, head=0, body=0;

    if (eyes>2)
        cout<<"Sorry, the beetle has only 2 eyes!";
    else if (antennas>2)
        cout<<"No more than 2 antennas";
    else if (wings>2)
        cout<<"nope, the beetle got 2 wings only";
    else if (head>1)
        cout<<"One head is enough";
    else if (body>1)
        cout<<"You got the body already";
    else if (legs>6)
        cout<<"Opps, you can't have more legs!";
    else
    {
        switch (num)
        {
            case 1:
                cout<<"You got an eye";
                eyes++;
                cout<<eyes;
                break;
            case 2:
                cout<<"\nYou got an antenna";
                antennas++;
                break;
            case 3:
                cout<<"\nYou got a leg";
                legs++;
                break;
            case 4:
                cout<<"You got a wing";
                wings++;
                break;
            case 5:
                cout<<"\nYou got the head";
                head++;
                break;
            case 6:
                cout<<"\nYou got the body";
                body++;
                break;
        }
    }
}  

int main()
{
    int n=0;
    cout<<"start?";
    cin>>n;
    while (n==1)
    {
        Die dice1; 
        dice1.roll();
        dice1.getNum();
        dice1.process();
        cout<<"\nRepeat?: ";
        cin>>n;
    }
}

2 个答案:

答案 0 :(得分:1)

当前int eyes=0, antennas=0, legs=0, wings=0, head=0, body=0;Die::process内的局部变量,这意味着它们被绑定到声明它们的范围。

每次执行该函数时,它们都将初始化为0,并且无法在当前写入的函数调用之间维护状态。


如果您希望将变量绑定到Die本身的实例,则应将它们添加为数据成员(1),如下例所示。

这样,值将保留在Die内的成员函数调用之间。

class Die
{
    private:
        int num;
        int eyes, antennas, legs, wings, head, body; // (1)

    public:
        int roll();
        int getNum();
        void process();

        Die () : eyes (0), antennas (0), legs (0), wings (0), head (0), body (0) { }; (2)
};

上面我们使用class Die构造函数在创建{{1}的实例时将它们全部初始化为0 (2)Die中删除有问题的变量名的声明。

答案 1 :(得分:1)

您将变量声明为函数的本地变量。这就是每次调用该函数时它们都被重置的原因。要保留函数调用之间的值,您必须将变量移动到类的成员中。

你的Die课程也没有很好的设计。你应该只为生成器播种一次,所以在构造函数中进行,然后创建一次Die对象,而不是每次循环迭代。并且您没有在新卷中使用最后一个卷,因此不需要在类中有num成员。

您还应该将甲虫逻辑与Die类分开。骰子不控制游戏。游戏使用骰子做出决定。您的代码应该反映出来。

尝试更像这样的东西:

#include <iostream>
#include <ctime>
#include <stdlib.h>

using namespace std;

class Dice
{
public:
    Dice();
    int roll();
};

class Beetle
{
private:
    int eyes;
    int antennas;
    int legs;
    int wings;
    int head;
    int body;

public:
    Beetle();
    void takeATurn(Dice &dice);
};

Beetle::Beetle() :
    eyes(0),
    antennas(0),
    legs(0),
    wings(0),
    head(0),
    body(0)
{
}

Dice::Dice() // initialize the dice
{
    srand((unsigned)time(0));
}

int Dice::roll() //roll one dice to get random number
{
    int num = (rand() % 6)+1;
    cout << num;
    return num;
}

void Beetle::takeATurn(Dice &dice) //player is building the beetle
{
    int num = dice.roll();

    if ((num != 6) && (body < 1))
    {
        cout << endl << "You need a body first";
        return;
    }

    switch (num)
    {
        case 1:
            if (eyes < 2)
            {
                eyes++;
                cout << endl << "You got an eye";
            }
            else
                cout << endl << "Sorry, the beetle has only 2 eyes!";
            break;
        case 2:
            if (antennas < 2)
            {
                antennas++;
                cout << endl << "You got an antenna";
            }
            else
                cout << endl << "No more than 2 antennas";
            break;
        case 3:
            if (legs < 6)
            {
                legs++;
                cout << endl << "You got a leg";
            }
            else
                cout << endl << "Opps, you can't have more legs!";
            break;
        case 4:
            if (wings < 2)
            {
                wings++;
                cout << endl << "You got a wing";
            }
            else
                cout << endl << "nope, the beetle got 2 wings only";
            break;
        case 5:
            if (head < 1)
            {
                head++;
                cout << endl << "You got the head";
            }
            else
                cout << endl << "One head is enough";
            break;
        case 6:
            if (body < 1)
            {
                body++;
                cout << endl << "You got the body";
            }
            else
                cout << endl << "You got the body already";
            break;
        }
    }
}  

int main()
{
    int n = 0;
    cout << "start?";
    cin >> n;
    if (n == 1)
    {
        Dice dice1; 
        Beetle beetle;

        do
        {
            beetle.takeATurn(dice1);
            cout << endl << "Repeat?: ";
            cin >> n;
        }
        while (n == 1);
    }

    return 0;
}