C++中的早期和晚期绑定+多态性

Early and late binding + polymorphism in c++

Say there was no Hello function and we simply called ob.display in main then it calls the display function of class B and not class A.

Call of the function display() is being set once by the compiler as the version defined in the base class. This is called static resolution of the function call, or static linkage - the function call is fixed before the program is executed. This is also sometimes called early binding because the display() function is set during the compilation of the program.

现在如何调用派生class的显示函数而不在基class的显示函数之前使用virtual关键字(后期绑定)?

现在在这个程序中,通过值调用传递对象、通过指针调用和通过引用调用 Hello 函数都可以正常工作。现在如果我们使用多态并且想要显示派生 class 的成员函数(如果它被调用)我们必须在基类中的显示函数之前添加 virtual 关键字。如果我们通过指针调用和引用调用传递对象值,它会调用派生的函数 class 但如果我们通过值传递对象,它就不会这样?>

class A
{
   public:
      void display();                       // virtual void display()
       {
        cout << "Hey from A" <<endl;
       }
};

class B : public A
{
    public:
        void display()
        {
            cout << "Hey from B" <<endl;
        }
};

void Hello(A ob) // &ob  //*ob
{
   ob.display();       // ob->display()
}

int main()
{
    B obj;
    Hello(obj); // obj   //&ob
    return 0;
} 

Now how can it call the display function of the derived class without using the virtual keyword(late binding) before the display function in the base class?

非虚函数只是由编译器根据调用它的对象(或引用或指针)的静态类型来解析。因此给定一个派生类型的对象,以及对其子对象的引用:

B b;
A & a = b;

调用非虚函数会得到不同的结果:

b.display();  // called as B
a.display();  // called as A

如果您知道真实类型,那么您可以指定要调用该版本:

static_cast<B&>(a).display();  // called as B

但是如果 a 引用的对象没有 B.

类型,那将是非常错误的

Now if we use Polymorphism and want to display the member function of the derived class if it is called we have to add the virtual keyword before display function in the base.

正确。如果您将函数设为虚函数,那么它会在运行时根据对象的动态类型进行解析,即使您使用不同类型的引用或指针来访问它也是如此。因此,以上两个示例都将其称为 B.

If we pass the object value by call by pointer and call by reference it call the function in the derived class but if we pass the object by value it doesn't why is it so?

如果你按值传递它,那么你就是切片它:只复制对象的A部分,创建一个[类型的新对象=16=]。因此,无论该函数是否为虚拟函数,在该对象上调用它都会选择 A 版本,因为它是一个 A 而只是一个 A.

如果您通过引用或指针传递,那么您仍在访问具有动态类型 B 的原始对象。因此,虚函数调用将解析为 B 版本。

Now how can it call the display function of the derived class without using the virtual keyword(late binding) before the display function in the base class?

您可以像这样提供模板化基础class

template<typename Derived>
class A {
   public:
      void display() {
        // call Derived first
        static_cast<Derived*>(this)->display();
        cout << "Hey from A" <<endl;
      }
};

class B : public A<B> {
public:
    void display() {
        cout << "Hey from B" <<endl;
    }
};

这是一个众所周知的模式,称为 CRTP 和静态多态性。