基指针中的派生对象如何调用基函数

How derived object in base pointer invokes base function?

本文关键字:调用 基函数 何调用 指针 派生 对象      更新时间:2023-10-16

如何保持基指针派生对象仍然指向基函数?Here After

a_ptr = &b_obj; 
a_ptr->disp();

如果基函数是虚函数,我理解v表的作用,它保存着基函数的地址。但是这里基指针处理派生对象可以设法调用基函数。

有谁能解释一下幕后发生了什么吗?

class A
{
 public:
 //virtual void disp()
 void disp()
 { cout<< "From class An" << endl; }
};
class B : public A
{
public:
 void disp()
 { cout << "From Class Bn" <<endl; }
};
int main()
{
 A a_obj;
 A *a_ptr;
 B b_obj;
 a_ptr = &a_obj;
 a_ptr->disp();
 a_ptr = &b_obj;
 a_ptr->disp();
}

基指针总是指向派生的对象的基部分。它不知道任何关于派生对象成员/方法的信息。

如果将方法A::disp()声明为virtual,那么在运行时只有它会被解析。它可以根据a_ptr指向的对象调用A::disp()B::disp()

简单来说,

  1. 如果你声明了一个方法virtual,那么编译器知道这个方法必须在运行时求值。此外,该方法必须使用指针或引用来调用。
  2. 如果该方法是使用对象调用的,或者该方法不是使用对象调用的然后,virtual编译器会直接调用的方法呼叫方静态类型

在您的示例中,调用方的静态类型是A*,而方法不是virtual。因此编译器会直接调用A::disp();它不会等待运行时评估。

a_ptr = &b_obj;  // static type --> typeof(*a_ptr) --> A
                 // dynamic type --> typeof(b_obj) --> B
a_ptr->disp();   // (is A::disp() virtual)?
                 // chooses B::disp() at runtime : chooses A::disp() at compiletime;

[注:假设如果您只使B::disp()作为virtual,并保持A::disp()正常方法,那么您仍然会得到与现在相同的结果。]