从const成员函数调用非const成员函数指针

时间:2016-04-24 13:15:25

标签: c++ c++11

我有以下代码:

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方法,试图调用类型为func_ptr的非const的函数指针。

我正在试图找出施展此方法的最佳方法。我可以使用标准的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?

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

此代码中存在一些问题。

| city_id | tag_id |
| 1       | 1      | 
| 1       | 3      | 
| 2       | 1      |
| 2       | 3      | 
| 3       | 1      |     
| 3       | 2      |
| 4       | 2      |     
| 5       | 1      |
| 5       | 2      |
| 5       | 3      |

不是格式良好的C ++,因为获取非静态成员函数的地址需要一个完全限定的名称:

select jaccard.city, 
       jaccard.intersect, 
       jaccard.union, 
       jaccard.intersect/jaccard.union as 'jaccard index'
from 
(select
    c2.name as city
    ,count(ct2.tag_id) as 'intersect' 
    ,(select count(distinct ct3.tag_id) 
      from cities_tags ct3 
      where ct3.city_id in(c1.id, c2.id)) as 'union'
from
    cities as c1
    inner join cities as c2 on c1.id != c2.id
    left join cities_tags as ct1 on ct1.city_id = c1.id
    left join cities_tags as ct2 on ct2.city_id = c2.id and ct1.tag_id = ct2.tag_id
where c1.id = 1
group by c1.id, c2.id) as jaccard
order by jaccard.intersect/jaccard.union desc

f = &MyFunc1; 在const成员函数中是 f = &MyClass::MyFunc1; 。您可能需要丢弃this

MyClass const*

更好的解决方案可能是重新考虑设计,以避免使用const来对抗类型系统。

答案 2 :(得分:0)

以下似乎是编译:

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

void MyFunc1()
{
    // ...
}

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