2014-02-21 83 views
1

說我有一類Foo有它返回一個非const引用的成員函數,它本身運行使用一個const this指針的成員函數:怎麼辦成員函數傳遞「this」指針

class Foo{ 
public: 
    Foo& display(std::ostream& os) { do_display(os); return *this; } 
private: 
    void do_display(std::ostream& os) const { os << contents; } 
    std::string contents; 
} 

display運行do_display時,this指針被隱式轉換爲指向const的指針。那爲什麼當do_display終止時,display仍然能夠改變它被調用的對象?據我所知,無法正常指定一個指向非const的指針的指針。任何見解都會被讚賞。

+3

你可以認爲它像一個參數。如果它爲一個函數添加了'const',那不會影響調用者。 – chris

+0

只有'do_display'不能更改對象。 'display'可以。這裏沒有魔術,因爲'this'是作爲第一個(隱藏的)參數傳遞的。 – zoska

+0

非const方法可以更改對象,即使它們調用一個const對象也是如此。方法就像另一個帶有隱藏的「第一個」參數的函數。 – Medinoc

回答

2

display中的非常量指針轉換爲do_display會創建一個不同類型的新指針;它不會更改現有指針的類型。傳遞this成員函數非常相似,將參數傳遞給非成員函數:

// A non-const member function receives `this` as a non-const pointer 
Foo& display(Foo * this, std::ostream & os) { 
    // Pass a copy of `this`, converted to `Foo const *` 
    do_display(this, os); 

    // The local `this` is still `Foo *` 
    return *this; 
} 

// A const member function receives `this` as a const pointer 
void do_display(Foo const * this, std::ostream & os) {os << this->contents;} 
+0

您是否體驗過使用較新的編譯器進行復制?我目前主要與老式的工作。 – Wolf

+1

@Wolf:你不會「體驗複製」,因爲傳遞'this'的機制是隱藏的。關鍵是將它傳遞給另一個成員函數不會在調用函數中改變它的類型,就像傳遞一個普通參數不會改變任何局部變量的類型一樣。 –

+0

好的,這就是我忘了:'this'指針是如此無所不在,我甚至不記得它必須傳遞給成員函數,並且在OP的例子中,這個調用肯定會被優化。 – Wolf

0

在C++ const訪問往往只有一個編譯時間屬性 [1]被引入,以減輕控制對象的狀態。 [2]

方法do_display()不會更改this的任何內容,但會限制其範圍內對只讀的訪問。在do_display()方法的調用返回之後,該訪問在display()方法的範圍內如前所述是可讀寫的。


[1]這是對選項cast const away,可以認爲是安全的原因,如果常量性是只是一個聲明之一。

[2]參見Item#3 Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition): Scott Meyers或例如Const Correctness - C++ Tutorials - Cprogramming.com