1

我正在学习类/继承/指针如何在 C++ 中工作并编写以下代码。

我有一个这样声明的类 单元

class unit{
    public:
        int locationX,locationY;

        //genotype (does not change)
        float agility, build,size,stamina, aggression;
        //phenotype (changes based on genotype and stimuli)
        float speed, strength, hunger;
};

当我创建一个新实例以传递给 void 函数(分别如下)时,尚未分配内存。

实例

unit **units = 0;

虚函数原型

void initialize(grid *grids, unit **units /*, plant **plants, predator **predators */);

使用一些参数在 void 函数中分配内存:

void initialize(grid *grids, unit **units,plant **plants,predator **predators)
{
    units = new unit*[int(((grids->gridHeight)*(grids->gridWidth)*(grids->gridDivision))/20)];

    for(register int i = 0; i<int(((grids->gridHeight)*(grids->gridWidth)*(grids->gridDivision))/20); i++)
        {
        units[i] = new unit;
        units[i]->hunger = 5;
        units[i]->locationX = (rand()%((grids->gridWidth)-0));
        units[i]->locationY = (rand()%((grids->gridHeight)-0));
        //etc, etc
    }
}

但是,一旦我退出 void 函数,我刚刚存储的数据就会被删除。指针声明和传递到函数中是否有问题(如下)?

initialize(&environment, units, plants, predators);

注意:我只有在unit类下声明的units变量有问题。环境变量没问题。其他两个(植物捕食者)类似于units,所以如果修复了,我可以修复其他的。

第二注:主要功能如下(相关部分):

int main()
{
    unit **units = 0; //<--- Important one
    plant **plants = 0;
    predator **predators = 0;
    grid environment(250,250,5); //Constructor for environment (don't mind this)
    initialize(&environment, units, plants, predators); //<-- Void function
    running = true;

    return 0;
}

感谢您提供的任何帮助/链接/解释。

4

3 回答 3

2

您按 value传递units给函数。这意味着函数中的指针一开始是调用代码中指针的副本。在函数中,您为局部变量分配一个新值(即一些新创建的对象的地址)。然后当函数终止时,局部变量超出范围,它指向的对象丢失。调用代码中的指针永远不会被修改,并且对此一无所知。unitsunits

而是通过引用传递它:

void initialize(grid *grids, unit ** &units)
于 2013-07-20T02:03:09.120 回答
1

您将“单位”作为堆栈中的“单位**”类型传递。当您为变量“units”分配一个新值时,您正在影响该函数的局部变量。如果您希望调用代码更新其变量“单位”,则必须通过指针或引用传递它。

解决此问题的最简单方法是将函数签名更改为:

void initialize(grid *grids, unit **&units, etc.. );

这是将变量单元作为对指向单元指针的指针的引用传递。

于 2013-07-20T02:05:10.273 回答
0

在方法内初始化指针(或数组)A * a是修改变量a(在本例中为指针/数组)的特殊情况。修改方法中的变量可以通过传递指向它的指针或引用来完成。所以如果你的变量已经是一个指针,这两个选项如下。

通过将指针传递给您的指针a

void init(A * *a)
{
    *a = new A(); // or "new A[n]" if "a" is an array
}

void main()
{
    A * a;
    init(&a);
}

或传递对您的指针的引用:

void init(A * &a)
{
    a = new A();  // or "new A[n]" if "a" is an array
}

void main()
{
    A * a;
    init(a);
}

所以在你的情况下,a是一个数组unit*(顺便说一下,我认为这是一个糟糕的设计,最好简单地使用一个数组unit并将你从这个循环中拯救出来以分别动态分配所有单元),所以基本上a是类型unit **所以你A实际上是 type unit*。使用第二种方法会导致:

void init(unit* * &units)

但正如我所说,最好简单地使用一个数组来unit代替,你的整个代码看起来像:

void initialize(unit * &units /* etc */)
{
    // note that I use unit instead of unit* here
    units = new unit[n];

    for(register int i = 0; i<n; i++)
    {
        // note that I remove the "new unit;" here
        // note that I use "." instead of "->"
        units[i].hunger = 5;
        units[i].locationX = (rand()%((grids->gridWidth)-0));
        units[i].locationY = (rand()%((grids->gridHeight)-0));
        //etc, etc
    }
}

void main()
{
    unit * units;
    initialize(units);
}
于 2013-07-20T02:55:00.150 回答