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

多态(1),咕咕咕!

1.多态的概念

多态分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要是函数重载和函数模版,传不同的参数调用不同的函数,达到多种形态。实参传给形参的参数匹配是在编译时完成的。

运行时多态就是去完成某个函数,可以传不同的对象完成不同的行为,达到多种形态。

2.多态的定义和实现

多态是一个继承关系下的类对象,去调用同一函数,产生不同的行为。必须是基类的指针或者引用调用虚函数(只有基类的指针或者引用才能既指向基类对象又指向派生类对象)。被调用的函数必须是虚函数,并且完成了虚函数重写/覆盖(派生类必须对基类的虚函数完成了重写/覆盖,才能又不同的函数)。

class person
{
public:
virtual void gugu()
{
cout<<"gugu"<<endl;
}
};
class student:public person
{
public:
virtual void gugu()
{
cout<<"gugugu"<<endl;
}
};
void func(person& p)
{
p.gugu();
}
void test()
{
person q;
func(q);//gugu
student a;
func(a);//gugugu
}

类成员函数前面加上virtual修饰,那么这个成员函数被称为虚函数,非成员函数不能加virtual修饰。

虚函数的重写/覆盖:派生类中有一个和基类完全相同的虚函数(派生类虚函数与基类虚函数的返回值类型,函数名字,参数列表完全相同),称派生类的虚函数重写了基类的虚函数。(在重写虚函数时,派生类的虚函数不加virtual关键字,也可以构成重写,因为继承后基类的虚函数被继承下来再派生类中依旧保持虚函数属性)

class person{
public:
virtual void gugu(){cout<<"gugu"<<endl;}
};
class student:public person
{
public:
virtual void gugu(){cout<<"gugugu"<<ednl;}
};
void func(person* ptr)
{
//虽然都是person指针ptr在调用gugu
//但是和ptr没关系,是由ptr指向的对象决定的
ptr->gugu();
}
int main()
{
person ps;
student st;
func(&ps);
func(&st);
return 0;
}
class A
{
public:
virtual void func(int val=1)
{
cout<<"A->"<<val<<ednl;
}
virtual void test()
{
func();
}
};
class B:public A
{
public:
void func(int val=0)
{
cout<<"B->"<<val<<endl;
}
};
int main()
{
B* p=new B;
p->test();
//B->1   调用了A的test函数,this->func()构成多态,多态时是重写虚函数的实现部分
//多态调用:父类虚函数声明+子类中实现部分,这里的this是A指针的
}B* p=newe B;
p->func();
//B->0    普通调用看指针或引用的类型,多态调用看指针或引用指向的对象

虚函数重写会有一些问题:

协变:派生类重写基类虚函数时,与基类虚函数返回值不同,基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用,称为协变,实际意义不大,了解即可。

析构函数的重写:基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同看起来不符合重写的规则,实际上编译器对析构函数的名称做了特殊处理,统一处理成destructor

class A
{
public:
virtual ~A()
{
cout<<"~A"<<endl;
}
};
class B:public A
{
public:
~B()
{
cout<<"~B"<<endl;
delete p;
}
protected:
int* p=new int[10];
};
//只有派生类student的析构函数重写了person的析构函数,下面的delete对象调用析构函数
//才能构成多态,保证p1,p2指向的对象正确调用析构函数
int main()
{
A* p1=new A;
A* p2=new B;
delete p1;
delete p2;
return 0;
}
如果~A不加virtual,那么delete p2时调用A的析构函数,没有调用B的析构函数,会内存泄漏

override和final关键字:c+=中虚函数重写的要求比较严格,但是有些情况由于疏忽,函数名写错参数写错等导致无法构成重写,在编译期间不会报出,运行时再debug才会发现,override可以帮助用户检测是否成功重写了。如果不想让派生类重写这个虚函数,可以用final修饰。

class car
{
public:
virtual void drive(){}
};
class gugu:public car
{
public;
virtual void drive()override{cout<<"gugu"<<endl;}
};
int main()
{
return 0;
}class car
{
public:
virtual void drive()final{}
};
class gugu:public car
{
public:
virtual void drive(){cout<<"gugu"<<endl;}
};
int main()
{
return 0;
}

 

http://www.dtcms.com/a/526731.html

相关文章:

  • xxx网站建设与优化推广网站视频弹窗代码
  • 在线制作网站源码渠道合作一站式平台
  • 个人如何做网站软件效果营销型网站建设
  • 大连网站的建设诚信档案建设网站
  • 做网站关于创新的太原网站制作计划
  • 域名备案与网站备案网站线下推广怎么做
  • 长沙网站建设深圳财务小公司网站
  • 织梦 网站栏目管理 很慢wordpress 安装数据库
  • 做网站的新闻定制型网站建设价格
  • 临安区建设局网站个人做外贸怎样起步
  • 长沙网站建计找网站做网站做网站
  • 滴滴业务模式,盈利模式,增长模式,商业模式
  • 可以自己做网站群晖外网打开wordpress
  • 家装网站建设预算wordpress做seo
  • seo网站怎么建设怎么做轴承网站
  • 罗湖商城网站设计费用网站设计 ipad
  • 网站数据库如何备份百度搜索关键词优化
  • 云虚服务器网站建设html5页面模板大全
  • 鸿蒙开发第4篇__配置文件config.json
  • iis添加网站访问权限工控主机做网站服务器
  • 西安哪家公司制作响应式网站建设怎么做影视类网站
  • 微餐饮网站建设wordpress 登陆接口
  • 怎么自己做论坛网站吗网站数据不变重新安装wordpress
  • 房地产网站模板 下载上海注册公司在哪个网站
  • 静态网站可以做哪些内容小红书怎么推广引流
  • 上海html5网站制作爱站网是什么平台
  • 网站开发图形化软件网站设计与实现
  • 免费网站在哪里申请表wordpress 324
  • Shell脚本中的命令会展开双引号中的变量但是单引号不行
  • 东营有什么网站建设公司工程建设合同模板