当前位置: 首页 > 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/750079/

相关文章:

  • 太原制作网站的公司网站天津seo霸屏
  • 建网站做站在外贸网站打开速度
  • 长春网站建设费用东莞网络营销公司
  • 移动端网站建设的软件有哪些网站商城微信支付
  • 做网站后端用户用什么写邢台做网站推广的公司是哪家?
  • 教育培训门户网站源码跟黄聪学WordPress主题开发
  • 上海seo网站优化软件网站新闻页面设计
  • 网站快速优化排名官网佛山做网站企业
  • 手机网站开发软件有哪些社交媒体营销
  • 昆明森贤网站建设装修室内设计培训学校
  • 国家建筑工程网653赣州网站优化
  • 专业做网站的公司哪家更专业云主机怎么安装网站
  • wordpress主题开发网站wordpress添加js代码
  • 常用网站建设技术有哪些域名网站可以做多个品牌产品吗
  • 色块网站设计营销展示型网站建设价格
  • 东莞废水处理 东莞网站建设郑州专业seo首选
  • 网站开发项目人员安排南昌莱布网络科技有限公司
  • 网站闪图怎么做的火车头wordpress发布模块制作
  • 深圳企业企业网站建设南山网站设计多少钱
  • 网站伪静态谈谈对seo的理解
  • 中山网站关键词排名wordpress留言表单
  • 做新闻封面的网站网站建设实习心得
  • 网站开发英文文献下载app安装到手机上
  • 长沙网站制作收费明细表哪里可以学网络运营和推广
  • 网站登录按钮点击没反应什么原因网站模板怎么修改logo
  • 息壤网站打不开了网站建设销售顾问开场白
  • 中国交通建设工程监督管理局网站桂林seo顾问
  • 免费做微信请帖的网站如何用自己的电脑做网站服务器
  • l兰州网站建设公司变更名称和经营范围
  • 网站域名和网站网址吗泊头做网站价格