2011-12-05 60 views
25

我有一個向量作爲類中的成員,我想通過getVector()函數返回對它的引用,以便稍後能夠對其進行修改。實踐getVector()函數是不是更好?然而,我在下面的代碼中遇到了一個錯誤,「限定符在類型綁定引用中被刪除」。應該修改什麼?對矢量成員變量的返回引用

class VectorHolder 
{ 
public: 
VectorHolder(const std::vector<int>&); 
std::vector<int>& getVector() const; 

private: 
std::vector<int> myVector; 

}; 

std::vector<int> &VectorHolder::getVector() const 
{ 
return myVector; 
} 

回答

27

由於它是const成員函數,所以返回類型不能是非const引用。做它const

const std::vector<int> &VectorHolder::getVector() const 
{ 
    return myVector; 
} 

現在沒關係。

爲什麼它很好?因爲在const成員函數中,每個成員都變成const以便它不能被修改,這意味着myVector是函數中的const向量,這就是爲什麼您必須使返回類型爲const以及if它返回參考

現在你不能修改相同對象。看看你可以做,哪些不能:

std::vector<int> & a = x.getVector();  //error - at compile time! 

const std::vector<int> & a = x.getVector(); //ok 
a.push_back(10);       //error - at compile time! 

std::vector<int> a = x.getVector();  //ok 
a.push_back(10);       //ok 

順便說一句,我不知道爲什麼你在第一個地方需要這樣的VectorHolder

+0

以這種方式則不可能從那裏返回它的代碼後修改返回向量? – arjacsoh

+0

@arjacsoh:這取決於。查看編輯。 – Nawaz

13

它的不尋常申報const和可變的變量,就像這樣:

std::vector<int>& VectorHolder::getVector() { 
    return myVector; 
} 
const std::vector<int>& VectorHolder::getVector() const { 
    return myVector; 
} 

與你的程序潛在的問題是,你從返回一個const方法的非const引用。

std::vector<int>& VectorHolder::getVector() const { 
    return myVector; // << error: return mutable reference from const method 
} 

所以你把它const的使用這種形式:

const std::vector<int>& VectorHolder::getVector() const { 
    return myVector; // << ok 
} 

並且當這是在非const的方法或客戶持有一個非const引用,則可以合法使用的非const的方法:

std::vector<int>& VectorHolder::getVector() { 
    return myVector; // << ok 
} 

最後,你可以返回一個值(在某些情況下):

std::vector<int> VectorHolder::getVector() const { 
    return myVector; // << ok 
} 

,因爲該副本不需要突變且不會暴露內部數據。

所以你最終會經常聲明這兩個變體。

宣佈兩者的結果是:

VectorHolder m; 
const VectorHolder c; 

m.getVector().size(); // << ok 
c.getVector().size(); // << ok - no mutation 

m.getVector().push_back(a); // << ok 
c.getVector().push_back(a); // << error: attempt to mutate const reference because the const vector is returned 

所以它均能工作(除了方法冗餘)出來。

2

函數getVector可以聲明爲const。它返回一個可以修改的引用,所以雖然實際函數不能修改類中的任何內容,但調用者將能夠修改內部數據。

聲明爲:

std::vector<int>& getVector(); 

如果你想有一個函數返回一個向量不能被修改,使用const修飾的載體和功能都:

const std::vector<int>& getVector() const; 
0

原因是一個const成員函數只應該返回const引用。這是因爲在const函數中,每個數據成員都是常量。

因此,你必須()這樣聲明getVector:

std::vector<int> &VectorHolder::getVector() const; 
+2

無論如何,暴露內部容器可能不是一個好主意。如果有一天你會決定從矢量遷移到地圖,你的用戶將會受到影響。我建議改爲實現迭代器。 – Lev