理解多态的实现原理

简介: 理解多态的实现原理

概念:

就是多个不同的对象,在完成某种相同动作时,会产生多种不同的状态。

就比如:一个音乐播放软件,会员和普通用户 能听的歌不一样,有些歌只有会员可以听,会员也可以选择听更好的音质。

class A
{
public:
  virtual void dunc()
  {
    cout << "Hello A" << endl;
  }
  int a;
};
class B : public A
{
public:
  virtual void dunc()
  {
    cout << "Hello B" << endl;
  } 
  int b;
};
class C : public A
{
public:
  virtual void dunc()
  {
    cout << "Hello c" << endl;
  }
  int c;
};
void func(A* ptr)
{
  ptr->dunc();
}
int main()
{
  A a;
  B b;
  C c;
  func(&a);
  func(&b);
  func(&c);
  return 0;
}

1d0e657f47ee4ad79bb3045cc2c7ad6e.jpg

多态有两个要求:

子类虚函数重写父类的虚函数(重写:函数名+返回值+参数相同、是虚函数)

由父类的指针或者引用去调用虚函数


特例:

协变:

class S
{};
class W :public S
{};
class A
{
public:
  virtual S* dunc()
  {
    S s;
    return &s;
  }
  int a;
};
class B : public A
{
public:
  W* dunc()
  {
    W w;
    return &w;
  } 
  int b;
};

只要父子关系的指针和引用做返回值都算 协变

子类虚函数没有写 virtual  父类虚函数写了是没有问题的


class A
{
public:
  ~A()
  {
    cout << "delete A" << endl;
  }
  int a;
};
class B : public A
{
public:
  ~B()
  {
    cout << "delete B" << endl;
  }
  int b;
};
int main()
{
  A* x = new A;
  delete x;
  A* y = new B;
  delete y;
  return 0;
}

大家觉得这段代码的运行结果是什么

d3f6e84e917c4857b498f48396de6e2f.jpg

普通调用就是正常的:

       x->destructor() + operator delete(x)

       y->destructor() + operator delete(y)

你这个变量是什么类型,就调用谁的析构函数。那如果加上virtual呢  

class A
{
public:
  virtual ~A()
  {
    cout << "delete A" << endl;
  }
  int a;
};
class B : public A
{
public:
  ~B()
  {
    cout << "delete B" << endl;
  }
  int b;
};
int main()
{
  A* x = new A;
  delete x;
  A* y = new B;
  delete y;
  return 0;
}

1a7d125edaa54486bb36cac877cd0b92.jpg

很明显这里就是一个多态调用了,先delete A 然后在子类的析构函数里面,先析构子类再析构父类

经过这也就得出一个结论:如果设计一个类,它可能作为基类的话,就需要给基类的析构函数添加上virtual 这样可以防止子类里面的资源泄露


final:

如果有不想要被继承或者被重写的类或者函数,就可以在类名 和 函数后面加上final

1. void func() final {}
2. 
3. class A final
4. {
5. };


override:

这个是用来放在子类里面去使用的,用于检查重写(函数名 + 参数 + 返回值)的完整性


抽象类、纯虚函数:

纯虚函数:在虚函数后面写上 =0 ,则这个函数为纯虚函数

抽象类:包含纯虚函数的类叫做抽象类


抽象类不能实例出对象。被继承后派生类也不能实例出对象,只有派生类重写虚函数,才能实例化出对象,纯虚函数也表明派生类必须重写,也体现出了接口继承


查表:

一个指针是不知道自己指向的是 派生类切割过来的 还是 指向自己类型 。所以在调用虚函数的时候会去查对应的虚函数表

class A
{
public:
  virtual void dunc()
  {
    cout << "Hello A" << endl;
  }
  virtual void dunc1()
  {
    cout << "dunc1" << endl;
  }
  int a;
};
class B : public A
{
public:
  virtual void dunc()
  {
    cout << "Hello B" << endl;
  }
  void dunc2()
  {
    cout << "dunc2" << endl;
  }
  int b;
};
int main()
{
  A X;
  B y;
  return 0;
}

c0cf56d90e374320988ceacf3959b32f.jpg

大家仔细地看这段代码,和这两个变量的内容:

首先,这两个虚函数表的地址是不同的;

A类里面的dunc1 是虚函数但是并没有在B类中重写,依然也是在A类的虚函数表里面的;

B类里面的虚函数表里面的第一个函数已经展现不清楚了,但我们依然知道它是重写后的dunc;


动态绑定:

静态绑定又叫前期绑定,在程序编译期间就确定了程序的行为:静态多态,比如:函数重载

动态绑定又叫后期绑定,在程序运行期间,根据具体拿到的类型确定程序的具体行为:动态多态

目录
相关文章
|
7月前
|
存储 Cloud Native 编译器
C++ 多态实现原理
C++ 多态实现原理
|
1月前
|
编译器 C++
继承和多态中的常见面试题(二)
继承和多态中的常见面试题(二)
|
10月前
|
存储 设计模式 编译器
【继承与多态常见面试题】建议收藏
【继承与多态常见面试题】建议收藏
90 0
|
1月前
|
编译器 Android开发 C++
【C++】一文简练总结【多态】及其底层原理&具体应用(21)
【C++】一文简练总结【多态】及其底层原理&具体应用(21)
|
6月前
|
存储 编译器 C++
C++中的多态机制
C++中的多态机制
|
8月前
|
存储 编译器 C++
【C++】多态的实现及其底层原理
【C++】多态的实现及其底层原理
|
10月前
|
存储 编译器 C++
【C++】多态及原理
【C++】多态及原理
30 0
|
11月前
|
设计模式
|
11月前
|
C++
【C++多态】 --- 多态实现原理简析
【C++多态】 --- 多态实现原理简析
76 0
|
编译器 C++ 开发者
C++虚函数详解:多态性实现原理及其在面向对象编程中的应用
在面向对象的编程中,多态性是一个非常重要的概念。多态性意味着在不同的上下文中使用同一对象时,可以产生不同的行为。C++是一种面向对象的编程语言,在C++中,虚函数是实现多态性的关键
121 0

热门文章

最新文章