当前位置: 首页 > news >正文

哈尔滨做网站的oeminc下载百度安装到桌面

哈尔滨做网站的oeminc,下载百度安装到桌面,app应用开发一般多少钱,网站服务内容网站建设目录 一. 多态 多态是什么 二. 多态的构成条件 1. 虚函数 2. 虚函数重写(隐藏) 3. 父类型的引用或者指针调用 4. 多态的特殊情况 1) 子类可以不加 virtual 关键字 2) 协变 三. 关键字 1. virtual 2. final 3. override 四. 多态的原理 1. 虚…

目录

一. 多态

多态是什么

二. 多态的构成条件

1. 虚函数

2. 虚函数重写(隐藏)

3. 父类型的引用或者指针调用

 4. 多态的特殊情况

1) 子类可以不加 virtual 关键字

2) 协变

三. 关键字

1.  virtual 

2. final

3. override

四. 多态的原理

1. 虚函数表指针

2. 调用原理

多态是怎么样被调用的?

多态为什么不能是父类的对象调用?

为什么需要是虚函数呢?

五. 总结


一. 多态

多态是什么

多态:简单的说就是不同类型的对象调用相同的函数产生的结果是不同的。

二. 多态的构成条件

  1. 虚函数重写

  2. 父类型的指针或者引用调用虚函数

1. 虚函数

虚函数就是一个函数前面加一个关键字 virtual 关键字,这样就是虚函数了,但是虚函数只能是成员函数才能是虚函数,而全局函数不可以成为虚函数。

virtual void fun()
{cout << "fun()" << endl;
}int main()
{return 0;
}

只有成员函数才可以是虚函数。

class A
{
public:virtual void fun(){}
};

 这样就是没有问题的。

2. 虚函数重写(隐藏)

我们的父类和子类只有函数三同才可以构成虚函数重写。

三同:函数名相同,参数相同,返回值相同,然后还需要是虚函数。

只有满足三同并且还都是虚函数才能构成重写。

class person
{
public:virtual void buyTicket(){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:virtual void buyTicket(){cout << "void student::buyTicket()" << endl;}
};

上面代码就是一个重写。

3. 父类型的引用或者指针调用

void fun(person& p)
{p.buyTicket();
}int main()
{person p;student s;fun(p);fun(s);return 0;
}

上面就是多态了。

如果我们破坏了里面的任意一个条件,那么就是不构成多态的,我们下面破坏掉虚函数的条件,让父类不是虚函数。

class person
{
public:void buyTicket(){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:virtual void buyTicket(){cout << "void student::buyTicket()" << endl;}
};void fun(person& p)
{p.buyTicket();
}int main()
{person p;student s;fun(p);fun(s);return 0;
}

 

此时我们的调用就是普通的 person对象 调用 buyTicket 函数。

我们在破坏一个其他的条件,返回值。

class student : public person
{
public:virtual void buyTicket(){cout << "void student::buyTicket()" << endl;}
};void fun(person& p)
{p.buyTicket();
}

 此时编译都不通过。

我们在破坏一个参数的条件。

class person
{
public:virtual void buyTicket(int a){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:virtual void buyTicket(){cout << "void student::buyTicket()" << endl;}
};

 此时编译也是不通过的,如果改变的是子类的参数,那么编译通过但是调用时不成功的。

 4. 多态的特殊情况

在多态里面,是由一些特殊情况的

1) 子类可以不加 virtual 关键字

class person
{
public:virtual void buyTicket(){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:void buyTicket(){cout << "void student::buyTicket()" << endl;}
};

我们的多态也是成功的,所以在多态这里我们的子类时可以不加 virtual 关键字的,但是基类时需要加的。

2) 协变

 协变就是参数可以不同,但是我们是有条件的,我们的协变只能是返回父类和子类的指针或者是引用。

class person
{
public:virtual person& buyTicket(){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:virtual student& buyTicket(){cout << "void student::buyTicket()" << endl;}
};

而且我们必选是同时是指针或者是引用,我们也不仅是可以是自己的父类和子类,我们也可以是其他的父类和子类。

class A
{};class B : public A
{};class person
{
public:virtual A& buyTicket(){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:virtual B& buyTicket(){cout << "void student::buyTicket()" << endl;}
};

而我们的返回值必须是父类返回父类,子类返回子类。

class person
{
public:virtual B& buyTicket(){cout << "void person::buyTicket()" << endl;}
};class student : public person
{
public:virtual A& buyTicket(){cout << "void student::buyTicket()" << endl;}
};

三. 关键字

1.  virtual 

virtual 关键字:

  • 虚继承:在继承的时候使用该关键字
  • 虚函数:在函数前面加 virtual 关键字

2. final

final 关键字:

  • 最终类:在类的后面加 final 表示该类无法被继承
class A final
{};class B : public A
{};

这里就是我们不能对 A 进行继承

3. override

override 关键字:

  • 检查是否完成重写:在派生类中使用,加在想要被重写的函数后面
  • 静态检查:在编译时静态检查,确保派生类中重写了基类的虚函数
class A 
{
public:void fun(){}
};class B : public A
{
public:void fun() override{}
};

 

 许哦一这里只需要完成重写就可以了。

class A 
{
public:virtual void fun(){}
};class B : public A
{
public:void fun() override{}
};

四. 多态的原理

1. 虚函数表指针

在前面的菱形虚拟继承继承中,如果有重定义的函数或者变量,那么里面是有一个虚基表的,这个是虚函数表指针,不要弄混了,下面看一下虚函数表指针。

在有虚函数的类中,该类都会有一个虚函数表指针,该指针就是指向该类中的虚函数的。

class A
{
public:virtual void fun(){}int _a;
};int main()
{A a;cout << sizeof(A) << endl;return 0;
}

这里的 sizeof 是8,所以这里的 A 肯定不只有一个 _a 的成员变量,还有一个虚函数表指针,这个是一个指针,所以在 32 位和 64 位下的环境是不同的。

下面1看一下该类的内部是怎么样的。

 

看一下这个指针里面的内容。

 

现在 a 这个对象里面只有一个虚函数,所以该表里面只存储一个,而虚函数表指针的本质,就可以理解为一个函数指针数组,该函数指针数组里面存储的就是一个个虚函数,如果还有其他的虚函数,那么还是会放在该类的这个虚函数表里面。

虚函数表:每个类共同使用一个虚函数表。

下面看一下相同类型的对象使用的虚函数表是否相同。

 

 

2. 调用原理

多态是怎么样被调用的?

多态是需要父类的对象或者是指针,然后调用重写的虚函数。

在父类的指针或者引用看来,它自己指向的对象模型就是一个父类对象。

class A
{
public:virtual void fun(){cout << "A::fun()" << endl;}int _a;
};class B : public A
{
public:virtual void fun(){cout << "B::fun()" << endl;}int _b;
};int main()
{B b;return 0;
}

这里看一下B 类型对象的对象模型

 所以在父类的引用或者指针看来就是一个父类的对象,但是调用为什么会形成多态?

看一下这个虚表指针里面的内容。

B 类型的对象里面的虚表指针里面是重写后的自己的虚函数,所以在调用的时候可以调用到自己的函数。

那么为什么B 类型的对象里面的虚表指针里面是自己的函数地址呢?下面分为3步。

  1. 在多态中,派生类首先会把基类的虚函数表拷贝下来。
  2. 如果派生类中对基类的虚函数进行了重写,那么就会将虚函数表中的基类的被重写的虚函数替换成自己的虚函数的地址。
  3. 如果自己也有自己的虚函数,就将自己的虚函数添加到虚函数表中。

 

多态为什么不能是父类的对象调用?

多态为什么不能是父类的对象呢?

int main()
{B b;A a = b;
}

现在将b 赋值给a,那么现在的a里面的虚表是父类的虚表还是子类的虚表?

当然是自己的,因为在父子类在进行赋值的时候,虚表是不会进行赋值的,如果虚表进行赋值的话,那么现在的 a 里面的虚表就是B 类型的虚表,那么a 对象调用虚函数的时候是调用的就是派生类的函数了,所以在进行赋值的时候虚表不能赋值,由于虚表在赋值的时候不能不拷贝,所以多态调用的时候不能是父类的对象。

int main()
{B b;A a;b._a = 10;a = b;
}

通过这段代码测试一下,这里将里面的 _a 变量赋值时为例更好的查看。

 

这里看到虚表时没有变化的。

为什么需要是虚函数呢?

前面说过了,虚函数会放到虚表里面,那么如果不是虚函数的话,那么当然是不会放在虚表里面的,所以如果函数都不在虚表里面即使是父类的指针或者是引用在虚表里面也找不到应该重写后的虚函数,所以也就没法实现多态。

五. 总结

多态

  • 多态的调用需要父类的引用或者是指针调用
  • 调用的函数必须是虚函数进行重写
  • 虚函数重写的条件是三同(函数名相同,返回值,参数)
  • 在多态这里子类是可以不加 virtual 的,只要父类加了,那么子类与父类的函数又是三同,就构成多态
  • 协变,协变就是返回值可以不同,但是返回值必须是父类返回父类的指针或者是引用,子类必须返回子类的指针或者是引用,而且返回的父子类只要是父子类既可以,不一定是自己的父子类 

http://www.shuangfujiaoyu.com/news/17999.html

相关文章:

  • 网站建设公司盈利模式公司官网模板
  • 赣州今日网络科技有限公司seo优化软件有哪些
  • 打开网上免费网站吗谷歌浏览器官网
  • 北京网站推广优化攀枝花网站seo
  • 网络营销视频网站关键词排名怎么优化
  • 凡科做网站技巧做网站怎么赚钱
  • 做ppt做好的网站职业技能培训机构
  • 做网站有好创意想法南宁seo结算
  • 毕业设计做网站用什么曹操seo博客
  • 做3d模型的叫什么牛的网站大众网疫情最新消息
  • 福州专业做网站交易链接
  • 抚松网站建设产品网络营销方案
  • 做鞋的网站利用搜索引擎营销成功的案例
  • 做公众号和网站一样吗快手刷评论推广网站
  • 中秋节网页设计代码安卓系统优化大师
  • 织梦网站建设网页今天微博热搜前十名
  • 做网站还赚钱吗如何找友情链接
  • 网络营销用什么软件天天seo站长工具
  • h5网页设计报告南昌网站seo
  • 做网站前端需要编程基础吗线上宣传的方式
  • 福田网站建设设计公司单页网站seo如何优化
  • 做原型网站推广任务接单平台
  • 德阳企业品牌网站建设什么是seo推广
  • 新疆建设委员会网站长沙百度网站快速排名
  • 银行虚拟网站制作网站怎样优化关键词好
  • 仓储管理系统软件排名超级seo助手
  • 潮州哪里做网站游戏代理0加盟费
  • 高端营销网站建设开鲁网站seo不用下载
  • 哪个网站上可以做初中数学题今日新闻头条最新消息
  • 宝塔wordpress建站教程湖北最新消息