我是一名C#程序员,现在正在使用C ++做一些工作。
pair<Point,double>* p=NULL;
Sphere* sphere=NULL;
for (int i=0;i<spheres.size();i++)
{
vector<pair<Point,double>> solution=findIntersection(Point(ray.origin),Point(ray.direction.x,ray.direction.y,ray.direction.z),spheres[i]);
if(solution.size()==0)
continue;
if(p==NULL || solution[0].second<p->second)
{
p=&solution[0];
sphere=&spheres[i];
}
}
if(p==NULL)
return backgroundColor;
else
{
Color c=localIlluminate(p->first,*sphere);
return c;
}
我希望p.first
具有最小值,sphere
是用于获取p
的相应范围。
调试后,我发现代码不起作用。在第一个循环中,p
将被赋予solution[0]
的地址,假设值为{(0,0),0}。然后循环继续,当i=1
时,假设解[0]变为{(1,2),3},p的值也变为{(1,2),3}。
我不希望p
的值发生变化。我该如何解决?
答案 0 :(得分:2)
您正在将声明的引用存储在声明局部变量的作用域之外。
每次迭代solution
都不再有效,那么它的地址不应被视为有效。要获得所需内容,您应该按值分配变量,以便实际复制包含的值,例如:
pair<Point, double> p = std::make_pair(whatever, std::numeric_limits<double>::max());
for (...)
{
if (solution[0].second < p.second)
p = solution[0];
}
地址变化的原因可能是由多种原因引起的,但你不应该理解为什么,只是避免这种情况。你的误解来自于C#有一个垃圾收集来防止solution[0]
变得无效,这在C ++中是不正确的,当在堆栈上声明变量时。
答案 1 :(得分:2)
当你指定给p时,它指向&amp; solution [0]的地址,但是在循环的下一次迭代中,变量变为poof并且创建了一个新的并且p指向随机的东西或其他东西。< / p>
将副本存储在p中可能更好,因此将p作为常规变量并通过分配复制解决方案[0]。您可以使用另一个bool变量来确定是否找到了解决方案。
pair<Point,double> p;
Sphere sphere;
bool solutionFound = false;
for (int i=0;i<spheres.size();i++)
{
vector<pair<Point,double>> solution=findIntersection(Point(ray.origin),Point(ray.direction.x,ray.direction.y,ray.direction.z),spheres[i]);
if(solution.size()==0)
continue;
if(!solutionFound || solution[0].second < p.second)
{
p=solution[0];
sphere=spheres[i];
solutionFound = true;
}
}
if(!solutionFound)
return backgroundColor;
else
{
Color c=localIlluminate(p.first, sphere);
return c;
}