2013-11-20 205 views
0

pointer()這些定義是相等的?從const成員函數返回類成員上的指針

class Example 
{ 
public: 
    AnotherClass* const pointer() const; 
    AnotherClass* pointer() const; 


private: 
    AnotherClass* m_pointer; 
} 

它保證我有人不能改變m_pointer指向的內存嗎?

+1

你想讓成員變量'm_pointer'保持不變,還是指向的內存? –

+0

指向的內存。謝謝,我沒有問確切的問題。 – Eugene

回答

1

pointer的兩個重載僅在返回類型上有所不同。你的C++編譯器不會接受,這是一個錯誤。

假設指針()只返回m_pointer:

聲明AnotherClass* pointer() const;將暴露m_pointer的值。該類的用戶將無法更改m_pointer,但可以更改m_pointer指向的對象。

聲明AnotherClass* const pointer() const;AnotherClass* pointer() const;非常相似,但返回的值(臨時指針)爲const。這個聲明沒有意義,因爲你已經不能在第一個聲明中改變返回值。在任何情況下都不能寫example.pointer() = nullptr。並且,如果將返回值分配給像p = example.pointer()這樣的變量,則指針()的返回值是否爲常量也沒有區別。

聲明const AnotherClass* pointer() const;AnotherClass const * pointer() const;會暴露m_pointer的值。該類的用戶將無法更改m_pointer,並且他們將無法更改m_pointer指向的對象。

+0

是模擬此: int * const和 int const *? – Eugene

+0

@Eugene對不起,我犯了一個錯誤。我現在更新了我的答案。希望現在更清楚。 –

2

您需要的第一種方法的返回類型是其中之一:

AnotherClass const * pointer() const; 

const AnotherClass* pointer() const; 

您所做的一切是常量指針返回到非const對象

你想要的是一個非常量指針到一個常量對象

此外,要遵循典型的做法,你的第二種方法不應該是const。

AnotherClass* pointer(); 
1

這裏要考慮幾件事情:

什麼是const:指針或指針對象?

讓我們看看這些不同的聲明之間的差異。

int x, y; 

int  *  p = &x; // 0 
const int *  p = &x; // 1 
int const *  p = &x; // 2 
int  * const p = &x; // 3 
const int * const p = &x; // 4 
int const * const p = &x; // 5 

(0)表示p可以改變(p = &y;是OK)以及它指向(x)可以通過p改變(*p = y;是OK)。

(1)和(2)是等價的,並意味着p可以改變(p = &y;是OK)以及它指向(x)不能通過p改變(*p = y;是錯誤的)。

(3)意味着p不能改變(p = &y;是誤差),並將其指向(x)什麼是可以改變經由p*p = y;是OK)

(4)和(5)是等效的,並意味着p無法更改(p = &y;是錯誤),它指向的內容(x)不能通過p更改(*p = y;是錯誤)。

一個簡單的方法來記住這是在看*,認爲它分離的對象常量性,就是

(一)const之前*(如const int * [...]int const * [...])是指尖銳的物體(類型int)是const;和

(b)一種const*(例如[...] * const p [...];)意味着指示器是const,並且不能被改變。

如果函數返回const對象會發生什麼?

考慮:

class some_class; 

const some_class a(); // equivalent to 'some_class const a();' 
     someclass b(); 

const int  c(); // equivalent to 'int const c();' 
     int  d(); 

然後,(假設some_class具有可訪問的賦值運算符),我們有:

some_class x; 

a() = x; // illegal : the returned object is const 
b() = x; // OK  : the returned object is not const 

是很自然的認爲,c()d()行爲相同,但這是案例:

c() = 0; // illegal 
d() = 0; // also illegal!!! 

原因是,如果函數返回基本類型(例如, int,bool,char,任何指針類型,...),那麼返回的對象不能被分配給。因此, 返回一個const基本類型的對象的行爲與返回非常量的對象相同

怎麼樣在返回類型上重載?

考慮

int f(); // first overload. 
double f(); // second overload. 

這是非法的。我們不能只在返回類型上重載。一個原因是我們總是可以忽略函數返回的對象。例如,如果允許在返回類型上重載,那麼將在下面調用哪個超載f

int main() { 
    f(); // which f? 
    return 0; 
} 

回答這個問題...

考慮第一個聲明

AnotherClass* const pointer() const; 

從我們所看到的,這意味着pointer()返回AnotherClass*類型的const對象(指針類型)。由於指針類型是一個基本的類型,功能pointer上述行爲相同,如果它是聲明爲

AnotherClass* pointer() const; 

這是第二過載。這是爲什麼有這兩個重載沒有意義的第一個原因。但與後面的相比,這只是一個薄弱的原因。

當我說「行爲相同」時,我並不是指「等效」。兩種重載的返回類型是不同的。正如我們所看到的,我們不能僅僅在返回類型上重載。這是非法的,代碼不能編譯。

它保證我有人不能改變m_pointer指向的內存嗎?

不,再次,無論重載行爲相同,並返回一個指針,可以通過該指針被改變的對象。你想要的是這樣的:

const AnotherClass* pointer() const { return m_pointer; } 
// or 
// AnotherClass const* pointer() const { return m_pointer; } 

通知的const*左側。

+0

一個非常深入的解釋const,驚訝你從不提及從右到左的閱讀順序約定。 –