代码之家  ›  专栏  ›  技术社区  ›  sdg

为什么我可以从const方法调用非const成员函数指针?

c++
  •  6
  • sdg  · 技术社区  · 14 年前

    一位同事问到,像这样的代码最初包含模板。

    我已经删除了模板,但核心问题仍然存在:为什么编译可以?

    #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是一个常量对象及其成员函数 执行 是常量,因此在cx::中执行 指针是常量。

    但我可以通过成员函数指针调用非常量成员函数。

    成员函数指针是不是一个记录在案的世界常数的漏洞?

    我们遗漏了什么(对其他人来说可能是显而易见的)问题?

    5 回复  |  直到 14 年前
        1
  •  8
  •   Georg Fritzsche    14 年前

    在这种背景下 object 是一个 参考A X 不是 对常量的引用 X . 这个 const 限定符将应用于成员(即引用,但引用不能 康斯特 ,而不是引用的对象。

    如果将类定义更改为不使用引用:

    // ...
    private:
        X object;
    // ...
    

    你会得到你期望的错误。

        2
  •  10
  •   AshleysBrain    14 年前

    这个 const 尼斯 execute() 只影响 this 类的指针。它使 const T* 而不仅仅是 T* . 不过,这不是一个“深度”常量——它只意味着成员本身不能被更改,但是他们指向或引用的任何内容仍然可以。你的 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
        }
    };
    
        3
  •  4
  •   Potatoswatter    14 年前

    实例 object 属于 class X 不是常数。它只被常量对象引用。常量递归地应用于子对象,而不是引用的对象。

    根据替代逻辑,a const 方法无法修改 任何东西 . 这被称为“纯函数”,是当前标准C++中不存在的概念。

        4
  •  2
  •   Vincent Robert    14 年前

    你在呼唤 foo object ,而不是 this .

    自从 对象 声明为 X& ,在常量cx中,它实际上是 X& const (与 const X& )允许对其调用非常量方法。

        5
  •  0
  •   Edward Strange    14 年前

    考虑到这一点,一个有用的方法可能是X对象根本不是CX的成员。