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

杭州大江东建设局网站西安建设工程信息网是谁开发的

杭州大江东建设局网站,西安建设工程信息网是谁开发的,怎么创建网页文件,企业培训课程价格目录 多态的实现 例题 重载 重写 重定义的区别 抽象类 多态实现原理 多态的实现 C中的多态是指,当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。多态意味着调用成员函数时,会根据调用函数的对象的类型来执…

目录

多态的实现

例题

重载 重写  重定义的区别

抽象类

多态实现原理


多态的实现

C++中的多态是指,当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。在C++中,通过将基类中的成员函数声明为虚函数,即可实现多态。

多态的发生是在继承的前提条件上,且要满足两个重要条件,否则都不能是多态:

1.虚函数的重写(要求三同,同函数名,同返回类型,同参数)-协变除外

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

这与我们普通调用函数时所观察的函数类型不一样,多态调用看的是调用指针或者引用指向的对象,指向父类调用父类函数,指向子类调用子类的函数,这里他看的是指针或者引用指向的对象。

其次虚函数的重写存在两个例外:

1. 协变(基类与派生类虚函数返回值类型不同)
派生类重写基类虚函数时,与基类虚函数返回值类型不同。即基类虚函数返回基类对象的指
针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。
class A{};
class B : public A {};
class Person {
public:virtual A* f() {return new A;}
};
class Student : public Person {
public:virtual B* f() {return new B;}
};
2. 析构函数的重写(基类与派生类析构函数的名字不同)
如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,
都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,
看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处
理,编译后析构函数的名称统一处理成destructor。
class Person {
public:virtual ~Person() { cout << "~Person()" << endl; }
};
class Student : public Person {
public:virtual ~Student() { cout << "~Student()" << endl; }
};
// 只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函
int main()
{Person* p1 = new Person;Person* p2 = new Student;delete p1;//调父类析构//此时子类析构调用虚析构且这里的析构函数是一种重写delete p2;//先调子类析构释放子类自己的那一部分空间,再调父类析构,释放剩下的父类的空间return 0;
}

其次我们要知道,只有对于 new子类对象给父类指针时,才会需要调用虚析构,去释放除了子类本身的那一部分空间,还要释放继承父类的那一部分空间,否则会造成内存泄漏。

例题

下面用几道题检验我们的水平:

这里正确答案选择c项,对于p1它是父类指针B1指向子类对象,由于切片的原因,所以p1就是表示Base1的空间同理p2指向Base2的空间。但是p3只想自己,也就是它包含了继承的父类的空间,按照声明的顺序,p3指向Base1+Base2+Derive,首地址的话就是Base1,故选择c。

该题正确答案是B,相信大家可能都会选择D项,首先我们知道p指针是一个子类指针,但他继承了父类的成员函数,所以调用test是父类的函数,test再次调用func函数(这里的调用还是父类this调用func函数,继承父类的),由于指向的对象是子类对象,且满足函数重写,故这里会去调用子类的func,但是记住一点,子类的函数只会重写函数体,对于参数和函数名函数类型都是继承父类的,所以这里的缺省参数应该还是父类里的。

重载 重写  重定义的区别

总的来说对于继承不是重写就是重定义,函数重载参数不同(参数类型,参数个数,参数类型顺序)。

抽象类

当一个基类的成员函数不仅仅添加了virtual,并且函数体为空,如:Drive()这个函数

class Car
{
public:
virtual void Drive() = 0;
};
class Benz :public Car
{
public:virtual void Drive(){cout << "Benz-舒适" << endl;}
};void Test()
{
Car* pBenz = new Benz;pBenz->Drive();
}

这样的函数我们将它称为纯虚函数,这样的类我们叫做抽象类。抽象类不能直接实例化对象

其次关键字overried可以检查虚函数是否完成重写。

多态实现原理

那么虚函数这种是怎么实现的呢?

在此之前我们先了解一下虚函数表:

首先对于虚函数的实现,在类中会有一个虚函数表指针,我们也可以根据类的大小看到有一个指针。

那么这个虚函数表指针是干嘛用的呢?

实际上一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中,虚函数表也简称虚表。
虚函数表本质上是一个指针数组,存放虚函数的指针。
父类是这样,那对于继承它的子类呢?我们用如下代码观察:
class Person {
public:virtual void Bytiket(){ cout << "成人买票全价" << endl; }virtual void Job(){ cout << "我是医生" << endl;}void habit(){cout << "打球" << endl;}private:int _b;
};
class Student : public Person {
public:virtual void Bytiket() { cout << "学生买票半价" << endl; }
private:int _d;
};
void Func(Person &p)
{p.Bytiket();}
int main()
{Person p;Student s;Func(p);Func(s);return 0;
}

首先对于父类,监视窗口并不能看到真正的情况,我们利用内存窗口再进行观察:

&p

 再详细的观察vfptr里面的内容

从内从中我们看到了确实和我们理解的一样,就是指针数组,里面存放着函数指针。

 此时我们再观察派生类里面的内容:

&s

vfptr

 可以看到子类中也有一个虚表指针,而且这与父类的虚函数表指针不一样,可以看到两者的虚函数指针地址都不一样,但是仔细观察里面存放的各个虚函数,可以看到第一个虚函数指针与父类的不一样,而第二个虚函数指针与父类的一样。

仔细一想我们大概就知道原因了,我们知道虚函数的重写其实是虚函数的覆盖,子类将虚函数表拷贝过来,在我们重写了某一个虚函数时,对应的虚函数指针就会被覆盖成新的,当我们不重写时,对应的虚函数地址没有发生改变,因此虚函数的重写本质上就是虚函数指针的覆盖。

完成覆盖后,当我们利用父类的指针或者引用指向子类对象,在调用时,就会调用完成覆盖后的虚函数的地址(新的虚表),此时调用的就是子类中重写的方法,这也就是我们会说调用的函数和指向的对象有关,指向子类调用子类的,指向父类调用父类的。本质就是指向某个对象的虚函数表。

那么又有一个问题我们也可以仔细想象了:为什么必须是父类对象的指针或者引用,对象就不行呢?

 了解到虚函数表的存在,我们再次思考,对象的指针或者引用那就是代表父类的这一部分的空间,指向子类对象时,中间不产生临时对象,可以当作切片剩下父类的那一部分,引用也就是直接引用那一部分。所以父类的引用与指针相当于就是子类中父类的那一部分空间,而我们用的是父类对象的话,父类对象指向子类对象,单单就是把子类中那父类的一部分给给父类但是不包括虚函数表,没有虚函数表多态就无法实现,故此必须是父类的指针或引用指向子类对象。

至于这里虚函数表不能拷贝,在设计之时就已经必须这样规定,如果虚函数指针也能被拷贝,那就全乱了,在调用时,该访问哪一个虚表?

http://www.yayakq.cn/news/962665/

相关文章:

  • 网站主色调有几种一起做网店17广州沙河
  • 夜场网站建设wordpress简洁风模板
  • 娱乐平台网站建设陕西建设网官方网站
  • 论述网站建设整个流程重庆建设集团公司
  • 惠州做企业网站的如何在公司网站下设置邮箱
  • 重庆美邦建网站商城小程序价格
  • 制作网站必做步骤制作返利网站
  • 高端电商网站开发手机访问跳转手机网站
  • 合肥企业网站建设工作室使wordpress没有手机页面
  • 个人建站公司wordpress获取时间
  • 上海网站排名优化丽水网站建设哪家好
  • 河北邯郸建网站站长网站素材网
  • 推荐聊城做网站索牛网站建设
  • 网站开发好学嘛西凤酒网站建设的基本情况
  • 自己做的网站怎么放上网怎么做网站的后台管理系统
  • 网站403错误网络优化案例分析
  • 网站怎么优化那些做环保网站的好处
  • 东莞网站设计讯息洛可可设计公司薪资
  • 做网站分辨率修改黄山学院教务管理系统
  • 网站设计开发是啥php网站建设基本流程
  • 12306网站开发商小程序源码模板下载
  • 全flash网站欣赏wordpress设置支付宝
  • 建个人网站怎么赚钱吗一个域名能同时做2个网站吗
  • 城乡建设厅建设网站关键词诊断优化全部关键词
  • 国内网站服务器中国水土保持生态建设网站
  • 一般电商都是在哪些网站上做太原免费建站
  • 网页网站建设的步骤流程广西做网站公司有哪些
  • 电子项目外包网站八戒网站做推广
  • 小米商城的网站建站海洋优质的网站建设
  • 湖南专业做网站公司宁海企业网站建设