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

发布于 2024-08-19 14:44:48 字数 1431 浏览 6 评论 0原文

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

这是我的类:

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);

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

先感谢您。

I am passing a value to copy constructor as a reference, but an infinite loop is being invoked.

Here's my class:

class Vector2f{
private:
    GLfloat x;
    GLfloat y;

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

    ~Vector2f();
};

Here's implementation of methods:

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()
{

}

Here's how I access the class:

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

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

The results I get are:

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
...

Infinite loop occurs when trying to initialize previously created object.
If I try to copy tempVector1 into tempVector 2 an infinite loop occurs as well:

Vector2f tempVector2;
tempVector2 = Vector2f(tempVector1);

Why does it happen and how can I prevent it from getting into an infinite loop?

Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

纵山崖 2024-08-26 14:44:48

这一行:

tempVector2 = Vector2f(tempVector1);

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

另外,您的代码在 Linux 上的 g++ 4.3.2 和 Mac 上的 g++ 4.2.1 上都运行良好(在我定义 getX、getY、将 DebugLog 转换为 printf 并使用 float 而不是 GLfloat 之后)。

This line:

tempVector2 = Vector2f(tempVector1);

would invoke operator=, not the copy constructor. Are you defining an operator= that is doing something wacky?

Also, your code worked fine for me with both g++ 4.3.2 on Linux and g++ 4.2.1 on Mac (after I defined getX, getY, converted DebugLog to printf and used float instead of GLfloat).

江城子 2024-08-26 14:44:48

我认为问题出在你的赋值运算符上。
运算符 = 是什么样子的?

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

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

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

请参阅 Exceptional C++,作者:Herb Sutter,了解更多详细信息)

I think the problem is in your assignment operator.
How does operator= look like?

It seems that operator= is calling him self in some way. Is it possible that the code snippet is taken from the body of operator= itself?

If it is then the solution is to change the code (inside operator=) such that it uses the copy ctor. The canonical form is as follows:

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

(See Exceptional C++ by Herb Sutter for more details)

沧笙踏歌 2024-08-26 14:44:48

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

Vector2f& operator =(const Vector2f& rhs);

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

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

tempVector2 = Vector2f(0.0f, 0.0f);

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

请注意,即使在 中,

tempVector2 = Vector2f(tempVector1);  

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

tempVector2 = tempVector1;  

分配将不会出现任何问题。如果事实证明这是编译器中的错误,这实际上是解决问题的方法:停止使用临时变量作为复制构造函数和复制赋值运算符的参数。

In the second case you are performing assignment, not construction. You haven't defined your own version of copy-assignment operator, which means that the compiler will provide one for you. The compiler-provided copy-assignment operator will be implicitly declared as

Vector2f& operator =(const Vector2f& rhs);

Note that the only parameter of this operator has a reference-to-const type.

In your code you are insisting on supplying a temporary rvalue object of type Vector2f on the right-hand side of assignment.

tempVector2 = Vector2f(0.0f, 0.0f);

This means that the reference parameter of the operator = is initialized with a temporary rvalue of class type. According to he language specification (8.5.3/5), the compiler is allowed to copy that temporary object as many times as it wants before actually attaching the reference. Eventually it must stop copying and finally call the operator. Normally compiler don't go crazy with the copying (most of them do no copying at all), however in your case this seems to be the issue. For some reason, your compiler gets locked in an infinite copying loop, never stopping it. I don't know what is causing this. Could be a bug in the compiler.

Note that even in the

tempVector2 = Vector2f(tempVector1);  

you are still supplying the right-hand side in form of a temporary rvalue. The rvalue is the result of the explicit cast to Vector2f you for some reason put there. I have no idea why you did this. If the problem is indeed in the compiler (and not in the code you are not showing us), I'm sure that if you do just

tempVector2 = tempVector1;  

the assignment will be carried out without any problems. This is actually how you can work around the issue if it turns out to be a bug in the compiler: stop using temporaries as the arguments to copy-constructor and copy-assignment operator.

唯憾梦倾城 2024-08-26 14:44:48

在IDE下运行。当它处于循环中时,按“暂停”按钮。您将清楚地看到问题所在。 原因如下。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文