【问题标题】:Calling non-virtual member function from base从基调用非虚拟成员函数
【发布时间】:2014-01-04 03:19:14
【问题描述】:

我快绝望了!我需要从指向我的基类的指针中调用一个非虚拟成员函数:

class A {  };

class B : public A { public: void evilFunction() { std::cout << "Yay!"; } };

int main(void) {
    A *pointer = new B();

    // Now do something like this: 
    // pointer->evilFunction();

    return 0;
}

我知道我可以使用 dynamic_cast 做到这一点 - 但我不允许这样做! 我真的不知道我还能做什么。从理论上讲,因为我有指针,我很确定我可以用指针算术做一些魔术来获取函数的内存位置然后调用它,但我不知道该怎么做,或者至少不知道怎么做开始。

谁能给我一个提示?这就是我所需要的。或者我将使用我史诗般的初学者技能编写代码来删除 g++,以报复 C++ 给我带来的痛苦!你不能让这种事情发生,对吧?!

【问题讨论】:

  • 这是一个教科书式的虚函数用例。
  • 事实上,你可以dynamic_cast做到这一点。
  • 你为什么需要...?
  • 在上面的代码中,如果你打算删除pointer,你需要先static_cast它,如Alf's answer所示。 delete pointer; 将是未定义的行为,除非您为 A 定义 virtual 析构函数。
  • @Seva Alekseyev:是的,就是这样。

标签: c++ class oop pointers function-call


【解决方案1】:

如果不想使用虚函数的原因是为了避免 RTTI,您可以使用 CRTP idiom 实现静态多态。

【讨论】:

    【解决方案2】:

    这里的主要问题是为什么不允许使用 dynamic_cast。

    如果这是因为您不使用 RTTI,而您仍然可以使用 static_cast - 这可能是您的答案。

    但是,如果这是因为代码标准或类似原因,我想 static_cast 或任何“魔术”也会被禁止,因此,您将不得不考虑另一种解决方案(例如,制作这种方法virtual,将“手动 typeid”添加到基类中,并相应地进行调度(讨厌这个...)等)

    【讨论】:

      【解决方案3】:

      当您知道指针确实指向B 时,只需使用static_cast


      int main()
      {
          A *pointer = new B();
      
          // Now do something like this: 
          // pointer->evilFunction();
          static_cast<B*>( pointer )->evilFunction();
      }
      

      【讨论】:

      • 非常感谢,我想就是这样!
      猜你喜欢
      • 2015-12-15
      • 1970-01-01
      • 2012-01-27
      • 2021-01-31
      • 2013-06-29
      • 1970-01-01
      • 2010-11-14
      • 2020-07-02
      • 2010-09-12
      相关资源
      最近更新 更多