【问题标题】:Calling non-const member function pointer from const member function从 const 成员函数调用非 const 成员函数指针
【发布时间】:2016-08-17 20:13:18
【问题描述】:

我有以下代码:

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?

【问题讨论】:

  • 怎么可能有一种干净的方法从const调用非const函数。其中一个函数是const 而另一个不是,这可能是有原因的。如果不是这样,只需修改 const 限定符。
  • 上面的评论(@FrankPuffer)应该被认为是这个问题 IMO 的正确答案。如果这些函数的“常量”确实不同,那么不要从 const 函数中调用非 const 函数。如果它们没有不同,则只需更改(不正确的)声明。

标签: c++ c++11


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这段代码有几个问题。

     f = &MyFunc1;
    

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

     f = &MyClass::MyFunc1;
    

    this 是 const 成员函数中的 MyClass const*。你可能需要抛弃那个const

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

    更好的解决方案可能是重新考虑设计以避免与const_cast 对抗类型系统。

    【讨论】:

      【解决方案3】:

      以下似乎可以编译:

      MyClass()
      {
          f = &MyClass::MyFunc1;
      }
      
      void MyFunc1()
      {
          // ...
      }
      
      void MyFunc2() const
      {
          MyClass* mc = const_cast<MyClass*>(this);
          (mc->*f)();
      }
      

      【讨论】:

      • 程序编译并不意味着它是有效的,或者是一个好主意。
      • 这是一个公平的观点。我不是故意这么说的,因为它编译得很好。我正在写这篇文章,同时另外两个人正在提供答案。看了他们的,好像代码部分有点相似。
      猜你喜欢
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 2010-12-26
      • 2011-03-04
      • 1970-01-01
      • 2016-02-26
      相关资源
      最近更新 更多