多态

1、代码

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
  virtual void print()
  {
    cout << "I'm Parent." << endl;
  }
};

class Child : public Parent
{
public:
  void print()
  {
     cout << "I'm Child." << endl;
  }
};

void how_to_print(Parent* p)
{
   p->print(); // 展现多态的行为
}

int main()
{
   Parent p;
   Child c;

   how_to_print(&p); // Expected to print: I'm Parent.
   how_to_print(&c); // Expected to print: I'm Child.

   return 0;
}

 

 

ps:

1、有一个父类和一个子类,他们各自有一个print函数(函数重写),如果发生了对象赋值(父类引用子类或者父类指针指向子类),然后调用对象的print函数,编译器为了安全直接调用的是父类的print函数,但是有时候我们需要的是调用子类的print函数。这就是多态,调用同一个函数可能调用的是父类的也可能是子类的。

为了解决这个问题,给父类的print函数加上virtual ,这样调用实际对象的print函数,编译器判断是父类对象还是子类对象,再调用实际的print函数。

函数重写必须实现多态才有意义

2、程序如何知道调用自己的或者是父类的函数呢?

当有继承和virtual函数时,每个类会有一个虚函数表,里面记录了所有函数的地址。

如class A;class B:A;

对于B来说它的虚函数表里首先会记录A的函数地址,如果某个函数是多态virtual的,那么会把这个函数的地址由A变为B,所以当调用这个函数的时候,实际上调用的是B的函数地址;当B有新的函数定义时,会在这个虚函数表里追加新的函数地址。

 3、继承时,最好把父类析构函数定义为虚函数。因为如果用父类指针指向子类实体对象,delete指针的时候默认调用的是父类的析构函数,如果父类的析构函数为virtual,则会依次调用子类和父类的析构函数。【通过实践:使用std的shared_ptr对指针管理时,即使父类的析构函数不是virtual,也会都调用】

posted @ 2018-01-21 12:25  朱小勇  阅读(164)  评论(0编辑  收藏  举报