【问题标题】:Confusion with the way in which derived class virtual function is being called与调用派生类虚函数的方式混淆
【发布时间】:2012-01-27 16:11:53
【问题描述】:

在下面的代码中,我无法理解调用派生类的虚拟方法的方式。 此外,任何人都可以建议一个资源,其中用非常基本的方法以图表方式解释虚函数的概念。

class Base1
{
  virtual void fun1() { cout << "Base1::fun1()" << endl; }
  virtual void func1() { cout << "Base1::func1()" << endl; }
};


class Base2 
{
  virtual void fun1() { cout << "Base2::fun1()" << endl; }
  virtual void func1() { cout << "Base2::func1()" << endl; }
};


class Base3 
{
    virtual void fun1() { cout << "Base3::fun1()" << endl; }
    virtual void func1() { cout << "Base3::func1()" << endl; }
};

class Derive : public Base1, public Base2, public Base3
{

public:

  virtual void Fn()
  {
    cout << "Derive::Fn" << endl;
  }

  virtual void Fnc()
  {
    cout << "Derive::Fnc" << endl;
  }
};


typedef void(*Fun)(void);

int main()
{
  Derive obj;
  Fun pFun = NULL;

  // calling 1st virtual function of Base1
  pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+0);
  pFun();

  // calling 2nd virtual function of Base1
  pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+1);
  pFun();

  // calling 1st virtual function of Base2
  pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+0);

  pFun();

  // calling 2nd virtual function of Base2

  pFun = (Fun)*((int*)*(int*)((int*)&obj+1)+1);
  pFun();

  // calling 1st virtual function of Base3
  pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+0);
  pFun();

  // calling 2nd virtual function of Base3
  pFun = (Fun)*((int*)*(int*)((int*)&obj+2)+1);

  pFun();

  // calling 1st virtual function of Drive
  pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+2);
  pFun();

  // calling 2nd virtual function of Drive
  pFun = (Fun)*((int*)*(int*)((int*)&obj+0)+3);
  pFun();

  return 0;
}

【问题讨论】:

  • 你所做的一切似乎都是未定义的行为,所以没有太多要解释的。

标签: c++ virtual


【解决方案1】:

您在显示的代码中所做的是使用“成员函数指针算术”来访问基类的虚函数,由于其奇怪的语法并且它们完全依赖于编译器,这非常难看。

我建议您阅读这篇关于快速委托的文章,以更深入地了解成员函数指针如何处理不同类型的继承:

http://www.codeproject.com/KB/cpp/FastDelegate.aspx

【讨论】:

  • 它不仅仅是“依赖于编译器”;这是未定义的行为。该标准不需要 vtable。
【解决方案2】:

继承图如下:

Base1  Base2  Base3

  \      |      /
   \     |     /
    \    |    /
     \   |   /

      Derived

没有明确的功能Derived::func1()。 Morover,virtual 关键字是一个红鲱鱼,因为Derived 实际上并没有覆盖任何东西。所以唯一的问题是如何调用各种基本函数。方法如下:

Derived x;

// x.func1(); // Error: no unambiguous base function

x.Base1::func1();
x.Base2::func1();
x.Base3::func1();

如果你真的覆盖 func1() in Derived,情况会完全不同。

【讨论】:

    猜你喜欢
    • 2014-01-25
    • 2014-03-22
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    相关资源
    最近更新 更多