[英]Invoking a nonconst method on a member from a const method
我驚訝地發現“const”中的這個“漏洞”:
#include <stdio.h>
class A
{
int r ;
public:
A():r(0){}
void nonconst()
{
puts( "I am in ur nonconst method" ) ;
r++;
}
} ;
class B
{
A a ;
A* aPtr ;
public:
B(){ aPtr = new A() ; }
void go() const
{
//a.nonconst() ; // illegal
aPtr->nonconst() ; //legal
}
} ;
int main()
{
B b ;
b.go() ;
}
因此,基本上從const
方法B::go()
,如果指針引用了類型A
對象,則可以調用非const成員函數(恰當地命名為nonconst()
)。
這是為什么? 看起來像一個問題(它在我的代碼中,我找到了它。)
當類型B
對象是const時,那么它的所有成員都是const,這意味着它的兩個成員在B::go()
的持續時間內有效
A const a;
A * const aPtr;
第一個是類型A
的常量對象,在該對象上只能調用const成員函數。 然而,第二個是指向非常數A
的常量指針。 你不能在函數B::go()
合法地說aPtr = <anything>
,因為這會修改aPtr
,它是常量。
指向一個恆定的A
將被宣布為A const* aPtr
或const A* aPtr
,那么這將使調用非恆定A::nonconst()
是非法的。
一個對象的“常量性” 不通過指針擴展到其它對象。 在您的示例中, const
部分是整個對象a
或指針 aPtr
。 因為aPtr
是A *
而不是const A *
,所以允許您調用非const方法。
如果你改變了
A* aPtr ;
至
const A* aPtr ;
那么你將無法調用aPtr->nonconst()
。
const
語言定義 我驚訝地發現“const”中的這個“漏洞”:
空無一人。
const
統一適用於所有類成員:在類C
的const
成員函數中, this
具有類型const C *
,因此對於聲明為類型T
的成員C::mem
:
class C {
// ...
T mem;
};
this->mem
類型為const T
請使用type來識別所有成員的聲明類型T
和相應的const限定類型。
看起來像一個問題(它在我的代碼中,我找到了它。)
僅僅因為規則的系統應用不符合您的預期並不意味着規則存在問題,這意味着您的期望存在問題。
你應該寫下你的期望,看看你是否期望一個非統一的應用程序,如果const
為不同的類型。
編程時,你必須在邏輯上進行推理。 你應該推斷出事物,而不是在沒有邏輯原因時期望它們。
const
這是為什么?
你的類被稱為A
和B
,很難理解什么構成邏輯狀態,什么不構成邏輯狀態。 ;)你問一個“道德”問題(不只是關於合法/非法C ++程序的問題),而你的代碼片段沒有“道德”價值。 如果您實際發布相關代碼,我們可能會做出一些“道德”判斷。
你應該聲明const
不會改變它所應用的對象的“邏輯狀態”的函數。
這意味着您必須定義類實例的“邏輯狀態” :它是一個抽象概念,只有您可以定義它,因為它是一個高級概念。 “邏輯狀態”與您的課程應該解決的問題有關。
然后你可以看出哪些變量對邏輯狀態有貢獻: *(b.aPtr)
有助於b
的邏輯狀態?
你知道拷貝構造函數嗎?
關於復制賦值運算符?
關於析構函數?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.