2016-04-24 178 views
0

我有以下代码:调用从const成员函数非const成员函数指针

class MyClass; 
typedef void(MyClass::*func_ptr)(); 
class MyClass 
{ 
public: 

MyClass() 
{ 
    f = &MyFunc1; 
} 

void MyFunc1() 
{ 
    // ... 
} 

void MyFunc2() const 
{ 
    (this->*f)(); 
} 

func_ptr f; 

}; 

如果我尝试编译,它失败,因为myfunc2所(中),这是试图调用函数一个const方法类型为非const的func_ptr指针。

我想弄明白这个最好的方法。我可以用一个标准的C风格的转换:

typedef void(MyClass::*func_ptr2)() const; 
    func_ptr2 f2 = (func_ptr2)f; 
    (this->*f2)(); 

但我宁愿使用C++投(即的static_cast,reinterpret_cast的,或者的const_cast)。我得到这个与reinterpret_cast编译,但我不能让它与const_cast一起工作。我认为const_cast不适合用于这种情况?另外,有没有更简单的方法来做到这一点,而无需创建另一个typedef?

+4

哪有一个** **清洁方式从'const'一个调用非'const'功能。可能有一个原因是为什么其中一个函数是'const',另一个不是。如果不是这样,只需修改'const'限定符。 –

+0

上面的评论(by @FrankPuffer)应该被认为是IMO这个问题的正确答案。如果这些函数的“常量”确实不同,那么**不要在const函数内调用非const函数。如果他们没有不同,那么只需更改(不正确)的声明。 –

回答

1

这段代码有几个问题。

f = &MyFunc1; 

不能很好地形成的C++,因为服用的非静态成员函数的地址需要一个完全合格的名称:

f = &MyClass::MyFunc1; 

this处于const成员函数MyClass const*。您可能需要抛弃那const

(const_cast<MyClass*>(this)->*f)(); 

一个更好的解决方案可能是重新思考设计,以避免与const_cast战斗类型系统。

2

典型的解决方案是(const_cast<MyClass*>(this)->*f)();

只要MyClass实例被创建为非const,这是合法的。 否则,这会调用未定义的行为。

0

下看起来编译:

MyClass() 
{ 
    f = &MyClass::MyFunc1; 
} 

void MyFunc1() 
{ 
    // ... 
} 

void MyFunc2() const 
{ 
    MyClass* mc = const_cast<MyClass*>(this); 
    (mc->*f)(); 
} 
+2

仅仅因为一个程序编译并不意味着它是有效的,或者一个好主意。 –

+0

这是一个公平点。我不是故意这么说,因为它编译起来很好。与此同时,我正在撰写这篇文章,其他两人正在提供答案。阅读他们的代码部分似乎有点类似。 –