3

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

这是我的课:

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

4 回答 4

6

这一行:

tempVector2 = Vector2f(tempVector1);

将调用 operator=,而不是复制构造函数。您是否正在定义一个 operator= 正在做一些古怪的事情?

此外,您的代码在 Linux 上的 g++ 4.3.2 和 Mac 上的 g++ 4.2.1 都可以正常工作(在我定义 getX、getY、将 DebugLog 转换为 printf 并使用 float 而不是 GLfloat 之后)。

于 2010-01-28T08:43:53.033 回答
1

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

Vector2f& operator =(const Vector2f& rhs);

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

在您的代码中,您坚持在赋值的右侧提供一个类型的临时右值对象。Vector2f

tempVector2 = Vector2f(0.0f, 0.0f);

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

请注意,即使在

tempVector2 = Vector2f(tempVector1);  

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

tempVector2 = tempVector1;  

任务将毫无问题地进行。如果它被证明是编译器中的错误,这实际上是您可以解决该问题的方法:停止使用临时变量作为复制构造函数和复制赋值运算符的参数。

于 2010-01-28T09:04:18.213 回答
1

我认为问题出在您的赋值运算符上。operator= 看起来如何?

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

如果是,那么解决方案是更改代码(在 operator= 内),使其使用复制 ctor。规范形式如下:

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

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

于 2010-01-28T08:49:15.373 回答
0

Run it under the IDE. When it's in the loop, press the "Pause" button. You will see exactly what the problem is. Here's why.

于 2010-02-19T17:52:11.623 回答