pointer()
這些定義是相等的?從const成員函數返回類成員上的指針
class Example
{
public:
AnotherClass* const pointer() const;
AnotherClass* pointer() const;
private:
AnotherClass* m_pointer;
}
它保證我有人不能改變m_pointer指向的內存嗎?
pointer()
這些定義是相等的?從const成員函數返回類成員上的指針
class Example
{
public:
AnotherClass* const pointer() const;
AnotherClass* pointer() const;
private:
AnotherClass* m_pointer;
}
它保證我有人不能改變m_pointer指向的內存嗎?
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指向的對象。
是模擬此: int * const和 int const *? – Eugene
@Eugene對不起,我犯了一個錯誤。我現在更新了我的答案。希望現在更清楚。 –
您需要的第一種方法的返回類型是其中之一:
AnotherClass const * pointer() const;
或
const AnotherClass* pointer() const;
您所做的一切是常量指針返回到非const對象。
你想要的是一個非常量指針到一個常量對象。
此外,要遵循典型的做法,你的第二種方法不應該是const。
AnotherClass* pointer();
這裏要考慮幾件事情:
什麼是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
在*
左側。
一個非常深入的解釋const,驚訝你從不提及從右到左的閱讀順序約定。 –
你想讓成員變量'm_pointer'保持不變,還是指向的內存? –
指向的內存。謝謝,我沒有問確切的問題。 – Eugene