2015-04-06 74 views
6

我檢查C++操作符重載和橫跨東西,我沒想到的,並有一些關於它的質疑來了。明確的拷貝構造函數編譯出錯

我的拷貝構造函數聲明並實現爲

explicit Vector(const Vector& v); 

Vector::Vector(const Vector& v) : 
_x(v._x), _y(v._y), _z(v._z) {} 

那麼我超載了複合賦值運算符

Vector Vector::operator+(const Vector& v) const 
{ 
    Vector tmp(*this); 
    tmp += v; 
    return tmp; 
} 

Vector Vector::operator-(const Vector& v) const 
{ 
    Vector tmp(*this); 
    tmp -= v; 
    return tmp; 
} 

然而,在return聲明我得到一個錯誤說no matching constructor for initialization of 'Vector'

自從我加入到我的構造函數中的唯一的事情就是explicit關鍵字,我刪除它和代碼編譯就好了,爲什麼呢?

我也從C++ 11檢查新的東西和發生,我可以宣佈我的構造就像一個移動的構造函數

explicit Vector(const Vector&& v); 

和代碼編譯就好了。如果我這樣做,我必須同時複製和移動構造函數嗎?

explicit Vector(const Vector& v); 
explicit Vector(const Vector&& v); 

或只是有移動構造函數會正常工作?如果我想堅持使用C++ 11,那麼遵循的正確方法是什麼?

+0

[顯式拷貝構造函數]可能的重複(http://stackoverflow.com/questions/11480545/explicit-copy-constructor) – Predelnik 2015-04-06 13:54:52

+0

很可能'+ ='和' - ='正在創建隱式拷貝,導致錯誤。 – NathanOliver 2015-04-06 13:56:49

+0

不是答案,而是對您的代碼的評論。根本沒有理由定義這樣的複製構造函數,因爲默認的構造函數完全一樣。通常也有理由聲明覆制構造函數是明確的,因爲它的目的是防止隱式類型轉換。 – MikeMB 2015-04-06 14:00:06

回答

5

你定義一個明確的拷貝構造函數,但功能

Vector Vector::operator+(const Vector& v) const 

Vector Vector::operator-(const Vector& v) const 

必須通過值返回,並且再也看不到了,因爲explicit(換句話說,他們不能複製tmp進入返回的對象)。

我也從C++ 11檢查新的東西和發生,我可以宣佈我的構造就像一個移動的構造函數 explicit Vector(const Vector&& v);和代碼編譯就好了。如果我這樣做,我必須同時複製和移動構造函數嗎?

不知道我理解你的意思在這裏。如果你只聲明一個顯式的移動構造函數(這會阻止編譯器生成一個默認的複製構造函數),你將會遇到同樣的問題。我無法制作「可編譯」代碼。

+0

我想我搞砸了。返回的值是左值還是右值?如果它是一個** rvalue **,我不能,而不是複製'tmp',使用C++ 11中新增的移動構造函數或移動操作。如果它是一個**左值**該函數將始終複製該值?編譯器有沒有優化? – BRabbit27 2015-04-06 14:43:05

+3

@BRabbit27返回值是一個右值,編譯器會盡可能地執行優化(它被稱爲*返回值優化*或RVO)。然而,如果你聲明移動/拷貝構造函數是「顯式」的,即使原則上可能進行優化,編譯器仍然抱怨「顯式」業務。這主要是因爲編譯器首先執行程序的正確性分析,然後應用優化。在優化階段之前,代碼應該是有效的C++。 – vsoftco 2015-04-06 14:51:04

+1

@ BRabbit27在C++ 11中,編譯器首先嚐試移動返回的對象(如果可能的話),如果不是,它會查找複製構造函數以複製它,如果它仍然沒有找到,它會發出錯誤。在這種情況下,您沒有任何隱式複製/移動構造函數。 – vsoftco 2015-04-06 14:52:37

0

通過返回值的對象,需要能夠執行一個隱含的複製結構。使複製構造函數顯式阻止。

這是真正的編譯器是否選擇不調用拷貝構造函數(例如,返回值優化)。