我在扩大我的面试问题。我创建了一个Rectangle类并实例化了其中的一些。调用解构函数时遇到了一个问题。 r1很好。 r2导致当机。因此,我手动调用了解构函数,并注意到它在r2上崩溃了。我以为它可能在删除时链接到r1,但事实并非如此。问题开始于此。
我正在更改r2的点值并打印出来。直到我上班之前,零钱还可以。 输入重载运算符<<时,point的值会更改。传入的变量rect获取该点的垃圾,更改了r2。
设置r2的点并打印:
r2.SetPoint({ 6.0f, 1.0f }); // Move r2
std::cout << "After moving r2: " << &r2 << std::endl;
我重载的运算符:
std::ostream& operator<<(std::ostream & out, Rectangle* rect)
{
return out << "x: " << rect->GetPoint()->x
<< " y: " << rect->GetPoint()->y
<< " width: " << rect->GetDimensions()->width
<< " height: " << rect->GetDimensions()->height;
}
为什么r2从打印语句中更改?
要查看我的所有代码,请参见my repository。 (请随时给我有关我的代码和标准的建议)
编辑:我认为它在我的构造函数中。我删除了两行,但仍然出现错误。看着我的构造函数,这些值最初很好,然后下一行它们就变坏了。
答案 0 :(得分:2)
print语句没有任何问题。发生实际问题的原因是您定义SetPoint
函数的方式。
r2.SetPoint({ 6.0f, 1.0f });
执行此操作时,将调用以下功能。
void Rectangle::SetPoint(Point2D _point)
{
this->point = &_point;
}
请注意,它是通过值传递的。如果您仔细观察它,就会知道它将导致未定义的行为。为什么?考虑一下:
void Rectangle::SetPoint(Point2D _point)
{
this->point = &_point; // this->point points to _point object.
} // _point dies here. So, accessing this->point will lead to UB.
建议:
1)不需要显式调用析构函数。您在main.cpp中做到了。一旦对象超出范围,将自动调用析构函数。
2)您的代码存在内存泄漏。
Point2D* point = new Point2D;
Dimensions* dimensions = new Dimensions;
如果我调用SetPoint()
和SetDimensions()
,则指向动态分配内存的指针将丢失。
3)将Getter定义为const
个函数。
4)在您的方案中避免浅复制。它将产生难以追踪的问题。