![](/img/trans.png)
[英]Why am I allowed to call a non-const member function from a const_iterator if the container element is a pointer?
[英]Why can I call a non-const member function pointer from a const method?
一位同事詢問了一些這樣的代碼,其中最初包含模板。
我已經刪除了模板,但核心問題仍然存在:為什么編譯正常?
#include <iostream>
class X
{
public:
void foo() { std::cout << "Here\n"; }
};
typedef void (X::*XFUNC)() ;
class CX
{
public:
explicit CX(X& t, XFUNC xF) : object(t), F(xF) {}
void execute() const { (object.*F)(); }
private:
X& object;
XFUNC F;
};
int main(int argc, char* argv[])
{
X x;
const CX cx(x,&X::foo);
cx.execute();
return 0;
}
鑒於CX是一個const對象,其成員函數execute是const,因此CX::execute內部的this指針是const。
但是我可以通過成員函數指針調用非常量成員函數。
成員函數指針是世界常量中記錄的漏洞嗎?
我們錯過了什么(對其他人來說可能很明顯)問題?
execute()
的const
性僅影響類的this
指針。 它使this
的類型成為const T*
而不僅僅是T*
。 雖然這不是一個“深”const——它只意味着成員本身不能改變,但他們指向或引用的任何東西仍然可以。 您的object
成員已經無法更改,因為無法重新定位引用以指向其他任何內容。 同樣,您不會更改F
成員,只是將其取消引用為成員函數指針。 所以這都是允許的,可以。
您創建 CX const 實例的事實不會改變任何內容:同樣,這指的是不允許修改直接成員,但他們指向的任何內容仍然可以。 你仍然可以在 const 對象上調用 const 成員函數,所以那里沒有變化。
為了顯示:
class MyClass
{
public:
/* ... */
int* p;
void f() const
{
// member p becomes: int* const p
*p = 5; // not changing p itself, only the thing it points to - allowed
p = NULL; // changing content of p in const function - not allowed
}
};
在此上下文中, object
是對X
的引用,而不是對 const X
的引用。 const
限定符將應用於成員(即引用,但引用不能是const
),而不是被引用的對象。
如果您將類定義更改為不使用引用:
// ...
private:
X object;
// ...
你會得到你期望的錯誤。
class X
的實例object
不是 const。 它僅被一個 const 對象引用。 常量遞歸地應用於子對象,而不是被引用的對象。
根據替代邏輯, const
方法將無法修改任何內容。 這被稱為“純函數”,這個概念在當前的標准 C++ 中不存在。
您在object
上調用foo
,而不是在this
。
由於object
被聲明為X&
,因此在常量 CX 中,它實際上是一個X& const
(與const X&
),允許您在其上調用非 const 方法。
一種有用的思考方式可能是您的 X 對象根本不是 CX 的成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.