我正在学习类/继承/指针如何在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 类下声明的单位变量有问题。 environment 变量很好。另外两个(植物和捕食者)与单位类似,所以如果修复了这个问题,我可以解决其他问题。
第二次注意:主要功能如下(相关部分):
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;
}
感谢您提供的任何帮助/链接/解释。
答案 0 :(得分:2)
您将units
传递给按值的功能。这意味着函数中的units
指针最初是作为调用代码中的指针的副本。在函数内,您为本地units
变量(即一些新创建的对象的地址)分配一个新值。然后,当函数终止时,局部变量超出范围,并且它指向的对象将丢失。调用代码中的指针永远不会被修改,并且对此任何内容都一无所知。
通过引用传递它:
void initialize(grid *grids, unit ** &units)
答案 1 :(得分:1)
您将“单位”作为堆叠中的“单位**”类型传递。为变量“units”分配新值时,会影响函数的本地变量。如果您希望调用代码更新它的变量“units”,则必须通过指针或引用传递它。
解决此问题的最简单方法是将您的功能签名更改为:
void initialize(grid *grids, unit **&units, etc.. );
这是将变量单位作为对指向单位指针的指针的引用传递。
答案 2 :(得分: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
实际上是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);
}