2011-05-26 86 views
4

我有這樣一個類:C++保護/公共重載

class Foo 
{ 
public: 
    Foo() 
    { 
     for(int i = 0; i < 10; ++i) 
      v.push_back(i); 
    }; 
    const vector<double>& V() const {return v;}; 
protected: 
    vector<double>& V() {return v;}; 
private: 
    vector<double> v; 
}; 

然後一塊這樣的代碼:

Foo foo; 
for(int i = 0; i < (int) foo.V().size(); ++i) 
    cout << foo.V().at(i) << endl; 

然而,後者提出了一個編譯錯誤稱V()通話是一種受保護的方法,而我只是試圖從中讀取,而不是修改它。

我試過以下(但沒有成功)。

Foo foo; 
const vector<double>& test = foo.V(); 
for(int i = 0; i < (int) test.size(); ++i) 
    cout << test.at(i) << endl; 

非常感謝您的幫助。

=====

謝謝大家的解釋和解決方案!非常感謝!

+0

如果你給一個'protected'引用賦予'private'變量,這有什麼意義? (我個人認爲這個邪惡)。 – 2011-05-26 07:45:28

回答

5

返回值無法超載。當對象是非常量時,將使用非const方法。有可能通過指導編譯器:

const vector<double>& test = const_cast<Foo const&>(foo).V(); 

或可能更好的解決方案是爲具有恆定方法具有不同的名稱(例如:ConstV)。或者你可以添加這個新方法,並保留當前的方法。這種方法用於C++ 0x標準。例如,常規方法cbegin()cend()已被添加到標準容器。

+0

Hooray安全使用'const_cast' – 2011-05-26 07:45:33

+1

錯誤的答案。 'const_cast (foo)'創建一個臨時對象,並在臨時對象上調用V()。 – Nawaz 2011-05-26 07:52:49

+2

你可能的意思是'const_cast (foo)'('const_cast'需要一個指針或引用)。更好的是使用'static_cast'。 – 2011-05-26 07:52:57

5

重載決議沒有考慮到成員的可訪問性,所以選擇一個理想的過載候選,然後然後成員可訪問性被檢查以查看該呼叫是否合法。

的現實的解決方法是:

Foo foo; 
Foo const& foo_alias = foo; 
for (std::size_t i = 0; i != foo_alias.V().size(); ++i) 
    cout << foo_alias.V().at(i) << endl; 
+0

不應該'const vector &v = foo.V()'調用好嗎?只有公共方法返回一個const向量? 謝謝。 – foo 2011-05-26 07:32:24

+0

@foo:不,這意味着你想要將返回值綁定到'const&'應該很重要,但重載解析也不考慮函數的返回類型。 – ildjarn 2011-05-26 07:33:46

+0

@foo:初始化表達式是'foo.V()';那裏沒有什麼「const」。 (在調用之後,*然後*它會將'const'標記到它上面。) – GManNickG 2011-05-26 07:38:38

2

由於fooconst編譯器正在嘗試使用非const方法。作爲解決方法,您可以執行以下操作:

Foo foo; 
    const Foo& cFoo = foo; 
    for(int i = 0; i < (int) cFoo.V().size(); ++i) 
    cout << cFoo.V().at(i) << endl; 
+0

您可以在'for'循環中使用'size_t',而不是在'(int)cFoo.V()。 ()'。畢竟,'at()'接受'size_type'類型的參數,它很可能是'size_t',或者* unsigned *整型。 – Nawaz 2011-05-26 08:10:01

+0

是的..我只是複製粘貼OP的代碼:) – Asha 2011-05-26 08:33:04

1

您已接近解決方案。如果Foo也是const,編譯器將選擇const函數。

Foo foo; 
const Foo& cfoo = foo; 

for(int i = 0; i < (int) cfoo.V().size(); ++i) 
    cout << cfoo.V().at(i) << endl;