为什么operator <<重载会更改变量的值?

时间:2019-02-16 00:00:03

标签: c++ c++11

我在扩大我的面试问题。我创建了一个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。 (请随时给我有关我的代码和标准的建议)

编辑:我认为它在我的构造函数中。我删除了两行,但仍然出现错误。看着我的构造函数,这些值最初很好,然后下一行它们就变坏了。

1 个答案:

答案 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)在您的方案中避免浅复制。它将产生难以追踪的问题。