2010-01-28 79 views
2

我傳遞一個值來複制構造函數作爲引用,但正在調用一個無限循環。複製構造函數調用一個無限循環

這裏是我的類:

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

它爲什麼會發生,我怎麼能阻止它進入一個無限循環?

預先感謝您。

+2

難道你不忘記Vector2f(const Vector2f&_vector)中的'&';'? – 2010-01-28 08:39:46

+0

@Kirill。真正。它不會編譯。找不到'getX'和'getY'。 – 2010-01-28 08:48:39

回答

1

我認爲問題出現在您的賦值運算符中。 運營商=看起來像什麼?

看來,運營商=正以某種方式稱他爲自己。代碼片段是否可能來自operator = body本身?

如果是這樣,解決方案是更改代碼(在operator =內部),以便它使用copy ctor。該規範形式如下:

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

(詳情請參見Exceptional C++由香草薩特)

+0

嗯。這個答案重複了R Samuel Klatchko的回答。接受重複的答案? – 2010-01-28 08:54:41

6

這條線:

tempVector2 = Vector2f(tempVector1); 

將調用運營商=,而不是拷貝構造函數。你是在定義一個運算符=這是在做一些古怪的事情嗎?我的g ++ 4.3.2和Mac上的g ++ 4.2.1(在我定義了getX,getY,將DebugLog轉換爲printf和使用float而不是GLfloat後),你的代碼對我來說工作得很好。

+2

我也會這麼說,有些代碼是不可見的。從上面顯示的代碼中,我看不到任何問題。 – jdehaan 2010-01-28 08:45:14

+0

謝謝問題不在複製構造函數中,而是在賦值運算符中。 – 2010-01-28 08:49:16

+0

不完全準確。首先,它會調用兩者,因爲顯式強制轉換(這將*調用複製構造函數)。其次,在初始化'operator ='的參數時,它可以根據需要多次調用拷貝構造函數。 – AnT 2010-01-28 15:11:32

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; 

分配將不會出現任何問題來進行。實際上,如果事實證明這是編譯器中的錯誤,那麼您可以如何解決該問題:停止使用臨時文件作爲複製構造函數和複製賦值運算符的參數。

0

在IDE下運行它。當它在循環中時,按下「暫停」按鈕。你會看到確切的問題。 Here's why.