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

时间:2010-03-26 13:26:02

标签: c++

一位同事问起这样的一些代码,其中最初有模板。

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

#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 ::执行这个指针是const。

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

成员函数指针是否是世界范围内记录在案的漏洞?

我们错过了什么(可能对他人来说很明显)?

5 个答案:

答案 0 :(得分:10)

const的{​​{1}}只会影响该类的execute()指针。它使this的类型为this,而不仅仅是const T*。这不是一个“深层”常量 - 它只意味着成员本身不能被改变,但他们指向或引用的任何东西仍然可以。您的T*成员已无法更改,因为无法重新定位引用以指向其他任何内容。同样,您不是更改 object成员,只是将其作为成员函数指针取消引用。所以这都是允许的,好的。

你制作你的CX const实例的事实并没有改变任何东西:再次,这指的是不允许被修改的直接成员,但是他们指向的任何东西仍然可以。您仍然可以在const对象上调用const成员函数,因此不会更改。

举例说明:

F

答案 1 :(得分:8)

在此上下文中,object是对X引用,而不是对const X 引用。 const限定符将应用于成员(即引用,但引用不能是const),而不是引用的对象。

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

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

你得到了你所期待的错误。

答案 2 :(得分:4)

object的实例class X不是常量。它仅由const对象引用。约束递归地应用于子对象,而不是引用的对象。

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

答案 3 :(得分:2)

您在foo上呼叫object,而不是this

由于object被声明为X&,因此在常量CX中,它实际上是X& const(与const X&不同),允许您调用非const方法就可以了。

答案 4 :(得分:0)

考虑它的一种有用方法可能是你的X对象根本不是CX的成员。