2013-02-06 68 views
2

我一直在學習C++,我與此刻類練習。 我創建了一個類,它存儲了玩家的名字和分數,並定義了一些函數來操縱數據並顯示它。返回「this」指針在const函數

其中一個我創建的功能是比較的兩名球員得分和指針 返回到播放器具有更高的分數。這是函數:

Player * Player::highestScore(Player p2)const 
{ 
    if(p2.pScore>pScore) 
    { 
     return &p2; 
    } 
    else 
    { 
     return this; 
    } 
} 

從主我創建以下球員:

Player p1("James Gosling",11); 
Player *p4 = new Player("Bjarne Stroustrup",5); 

我所說的highestScore功能:

Player *highestScore = p1.highestScore(*p4); 

但是正如你可能已經從閱讀注意函數本身,當我將指針返回到調用該方法的對象時(如果它的分數較高),我得到一個錯誤消息:

return value type does not match the function type 

這個問題似乎當我聲明函數的返回類型爲const,像這樣消失:

const Player * Player::highestScore(Player p2)const 

是困惑我的是,爲什麼它讓我return &p2的一部分,這是不const並且不允許我回去this,這是一個指向調用的函數,這是不是一個const以及對象?即使傳遞給參數的參數不是一個const Player對象,即使我將函數返回類型聲明爲const,它仍然允許我使用return &p2

如果這個問題似乎很奇怪或什麼,我試圖做的是非常糟糕的編程,但它做它只是一個學習的目的對不起。

+0

這個以前回答的問題可能有幫助 - http://stackoverflow.com/questions/6919330/return-this-in-c –

+3

'this'是const,因爲成員函數被聲明爲const。參數'p2'不會在參數列表中聲明爲'const',因此您可以*返回它的地址,但是請注意這樣做,您將返回由-val推送的堆棧變量的地址,以及因此,如果該地址在您的成員函數外被引用,則是未定義的行爲。 – WhozCraig

+0

@WhozCraig:對,他可能是指'const Player * Player :: highestScore(Player&p2)const',使用參考 –

回答

6

是困惑我的是,爲什麼它讓我回到& P2,這不是常量,不允許我回到這一點,這是一個指向調用該函數的對象的一部分,其中也不是一個常量?

thisconst(或者,更準確地說,是一個指針TO- const)在const成員函數,就像所有數據成員:

#include <iostream> 
#include <type_traits> 

struct A 
{ 
    void foo() 
    { 
     std::cout << std::is_same<decltype(this), const A*>::value << '\n'; 
    } 

    void bar() const 
    { 
     std::cout << std::is_same<decltype(this), const A*>::value << '\n'; 
    } 
}; 

int main() 
{ 
    A a; 
    a.foo(); 
    a.bar(); 
} 

Output

0 
1 

而且即使當我宣佈函數返回類型爲常量,它仍然可以讓我回到& P2,即使傳遞給該參數的參數不是一個常量Player對象?

我們不能看到你嘗試過什麼,但想必是Player* const,這是不一樣的Player const*(或const Player*)。你可以添加const ness到&r2就好了;採取const奈斯是一個不同的故事。

+0

感謝您的回答。如果你的意思是你看不到我是如何嘗試從main中初始化p2參數的指針的,我在下面做了這個: Player * p4 = new Player(「Bjarne Stroustrup」,5); –

+0

不,我的意思是,我們沒有看到你的嘗試,「將函數返回類型聲明爲const」。但沒關係。 –

3

const和non-const方法之間的區別在於,const中的第一個指針this中的指針不是。所以,當你試圖從const函數返回非const指針並返回時,編譯器會抱怨,因爲this是const並且const_ness不能被自動刪除。

&p2只是一個指向參數的指針,因此它不是const。請記住,雖然&p2是指向本地變量的指針,但它不可能安全返回

3

當你有一個「const」函數時,你幾乎承諾「我們不會在這個調用中改變對象實例」。編譯器爲該類型的函數(其中T是類的類型,例如Player)製作this a const T* this

顯然,指針返回的東西是const作爲一個非const指針是違反規則的 - 因爲一旦一些代碼有一個非const指向你的對象,代碼可以修改對象..這打破了「這個功能不會修改」的承諾。

因此,將const添加到函數的返回類型中是正確的解決方案。

你可能還想改變你的代碼,以便它需要一個const *Player p2作爲輸入 - 你當前的代碼返回一個指向局部變量的指針[它恰好是一個參數,但它是相同的原理 - 它不存在當函數調用返回時]。

編輯:除非您實際上在具有const屬性的函數中返回某個東西的副本(例如,整數,字符串或分配了新的結構的新結構),否則返回類型應爲const

+0

啊我明白了。那麼該函數是否允許我返回一個指向p2的指針,因爲它是一個指向局部變量的指針,因此編譯器不會將它指向一個常量指針? –

+2

你被允許從const函數返回一個非常量的指針 - 如果返回的值是一個指針或引用某個對象本身的內容,通常不是一個好主意[例如,'this'或者'this-> something'在ponter的情況下] - 因爲這意味着調用代碼可以稍後修改您承諾的內容不會被修改的內容。 –

+0

感謝您爲我清除它。 –