簡體   English   中英

為什么我可以從 const 方法調用非常量成員函數指針?

[英]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
    }
};

在此上下文中, objectX引用,而不是對 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM