复制构造函数调用无限循环

时间:2010-01-28 08:33:47

标签: c++ infinite-loop copy-constructor

我传递一个值来复制构造函数作为引用,但是正在调用一个无限循环。

这是我的班级:

class Vector2f{
private:
    GLfloat x;
    GLfloat y;

public:
    Vector2f();
    Vector2f(const GLfloat _x, const GLfloat _y);
    Vector2f(const Vector2f &_vector);

    ~Vector2f();
};

这是方法的实现:

Vector2f::Vector2f():
        x( 0.0f ),
        y( 0.0f )
{
    DebugLog("Vector2f constructor");
}

Vector2f::Vector2f(const GLfloat _x, const GLfloat _y):
        x( _x ),
        y( _y )
{
    DebugLog("Vector2f constructor(%f, %f)", _x, _y);
}


Vector2f::Vector2f(const Vector2f &_vector):
        x( _vector.getX() ),
        y( _vector.getY() )
{
    DebugLog("Vector2f copy constructor");
}

Vector2f::~Vector2f()
{

}

以下是我访问该课程的方法:

Vector2f tempVector1 = Vector2f(0.0f, 0.0f);
DebugLog("tempVector1 initialized");

Vector2f tempVector2;
tempVector2 = Vector2f(0.0f, 0.0f);
DebugLog("tempVector2 initialized");

我得到的结果是:

Vector2f constructor(0.000000, 0.000000)
tempVector1 initialized
Vector2f constructor
Vector2f constructor(0.000000, 0.000000)
Vector2f copy constructor
Vector2f copy constructor
Vector2f copy constructor
...

尝试初始化以前创建的对象时发生无限循环。 如果我尝试将tempVector1复制到tempVector 2中,也会发生无限循环:

Vector2f tempVector2;
tempVector2 = Vector2f(tempVector1);

为什么会发生这种情况,如何防止它进入无限循环?

提前谢谢。

4 个答案:

答案 0 :(得分:6)

这一行:

tempVector2 = Vector2f(tempVector1);

会调用operator =,而不是复制构造函数。你是在定义一个运算符=做一些古怪的事情吗?

另外,你的代码在Linux上使用g ++ 4.3.2和在Mac上使用g ++ 4.2.1(在我定义了getX,getY,将DebugLog转换为printf并使用float而不是GLfloat之后)对我来说很好。

答案 1 :(得分:1)

我认为问题出在你的赋值运算符中。 operator =看起来怎么样?

似乎operator =以某种方式称他自己。代码片段是否可能是从operator =本身的主体中获取的?

如果是,则解决方案是更改代码(在operator =内),以便它使用copy ctor。规范形式如下:

Vector2f temp = Vector2f(arg);
swap(*this, temp)   // You need to implement a swap method
return *this; 

(有关详细信息,请参阅Herb Sutter的Exceptional C++

答案 2 :(得分:1)

在第二种情况下,您正在执行任务,而不是施工。您尚未定义自己的复制赋值运算符版本,这意味着编译器将为您提供一个。编译器提供的复制赋值运算符将隐式声明为

Vector2f& operator =(const Vector2f& rhs);

请注意,此运算符的唯一参数具有引用到const类型。

在您的代码中,您坚持在分配的右侧提供类型为Vector2f临时右值对象。

tempVector2 = Vector2f(0.0f, 0.0f);

这意味着operator =的引用参数初始化为类类型的临时rvalue。根据他的语言规范(8.5.3 / 5),允许编译器在实际附加引用之前复制该临时对象多次。最终它必须停止复制并最终调用操作员。通常编译器不会因复制而疯狂(大多数都没有复制),但在你的情况下,这似乎是问题所在。出于某种原因,您的编译器被锁定在无限复制循环中,从不停止它。我不知道造成这种情况的原因。可能是编译器中的错误。

请注意,即使在

中也是如此
tempVector2 = Vector2f(tempVector1);  

你仍然以临时右手的形式提供右手边。右值是由于某种原因显式转换为Vector2f的结果。我不知道你为什么这样做。如果问题确实存在于编译器中(而不是代码中你没有向我们展示),我肯定如果你这样做的话

tempVector2 = tempVector1;  

任务将毫无问题地进行。这实际上是如何解决问题,如果它在编译器中是一个错误:停止使用temporaries作为复制构造函数和复制赋值运算符的参数。

答案 3 :(得分:0)

在IDE下运行它。当它处于循环中时,按“暂停”按钮。您将确切地看到问题所在。 Here's why.