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

漯河网站建设lhwzzz大理企业网站建设

漯河网站建设lhwzzz,大理企业网站建设,国防教育网站建设说明书,支持付费下载系统的网站模板或建站软件目录 一、多态的概念和虚函数 1.1 - 用基类指针指向派生类对象 1.2 - 虚函数和虚函数的重写 1.3 - 多态构成的条件 1.4 - 多态的应用场景 二、协变和如何析构派生类对象 2.1 - 协变 2.2 - 如何析构派生类对象 三、C11 的 override 和 final 关键字 一、多态的概念和虚…目录 一、多态的概念和虚函数 1.1 - 用基类指针指向派生类对象 1.2 - 虚函数和虚函数的重写 1.3 - 多态构成的条件 1.4 - 多态的应用场景 二、协变和如何析构派生类对象 2.1 - 协变 2.2 - 如何析构派生类对象 三、C11 的 override 和 final 关键字 一、多态的概念和虚函数 1.1 - 用基类指针指向派生类对象 基类指针可以指向派生类对象但是通过基类指针只能使用基类的成员包括成员变量和成员函数不能使用派生类的成员 #include iostream using namespace std; ​ class Person { public:Person(const char* name 张三, int age 18): _name(name), _age(age){ } ​void Print() const{cout _name 今年 _age 岁了。 endl;} protected:string _name;int _age; }; ​ class Student : public Person { public:Student(const char* name 张三, int age 18, int id 0): Person(name, age), _id(id){ } ​void Print() const{cout _name 今年 _age 岁了学号是 _id 。 endl;} protected:int _id; }; ​ int main() {Person p(李四, 19);Person* pp p;pp-Print();  // 李四今年19岁了。Student s(王五, 20, 2);pp s;pp-Print();  // 王五今年20岁了。return 0; } 1.2 - 虚函数和虚函数的重写 如果在基类的成员函数前面加上 virtual 关键字把它声明为虚函数并且在派生类中对基类的虚函数进行重写覆盖那么当基类指针指向派生类对象时就可以调用派生类中同名的成员函数通过派生类中同名的成员函数也就可以访问派生类对象的成员变量。 当派生类中有一个跟基类完全相同的虚函数时即派生类虚函数与基类虚函数的返回值类型、函数名、参数列表完全相同就称派生类重写覆盖了基类的虚函数。 #include iostream using namespace std; ​ class Person { public:Person(const char* name 张三, int age 18): _name(name), _age(age){ }// 声明为虚函数virtual void Print() const{cout _name 今年 _age 岁了。 endl;} protected:string _name;int _age; }; ​ class Student : public Person { public:Student(const char* name 张三, int age 18, int id 0): Person(name, age), _id(id){ }// 注意在派生类中重写基类的虚函数时派生类的虚函数可以不加 virtual 关键字// 但是这种写法不是很规范不建议这样操作。virtual void Print() const{cout _name 今年 _age 岁了学号是 _id 。 endl;} protected:int _id; }; ​ int main() {Person p(李四, 19);Person* pp p;pp-Print();  // 李四今年19岁了。Student s(王五, 20, 2);pp s;pp-Print();  // 王五今年20岁了学号是2。return 0; } 有了虚函数基类指针指向基类对象时就使用基类的成员函数指向派生类对象时就使用派生类的成员函数基类指针表现出了多种形态这种现象我们称之为多态Polymorphism。 1.3 - 多态构成的条件 通过以上的内容可以总结出构成多态的条件 必须存在继承关系 继承关系中派生类必须对基类的虚函数进行重写。 必须通过基类的指针或引用调用虚函数。 因为引用在本质上是通过指针的方式实现的所以既然借助基类指针可以实现多态那么借助基类引用也可以实现多态。 Person rp p; p.Print();  // 李四今年19岁了。 Person rs s; rs.Print();  // 王五今年20岁了学号是2。 1.4 - 多态的应用场景 在应用开发中我们可以在基类的成员函数中实现基本的功能并且把基类的成员函数设置为虚函数留给派生类去扩展和优化、实现个性化的功能。 当然要达到以上的目的不一定要使用虚函数和多态例如 #include iostream using namespace std; ​ class Hero { public:void skillQ() { cout 英雄释放了 Q 技能 endl; }void skillW() { cout 英雄释放了 E 技能 endl; }void skillE() { cout 英雄释放了 W 技能 endl; }void skillR() { cout 英雄释放了 R 技能 endl; } protected:int HP;  // 体力值、血量int MP;  // 魔法值int AD;  // 物理伤害int AP;  // 法术伤害 }; ​ class A : public Hero { public:void skillQ() { cout 英雄 A 释放了 Q 技能 endl; }void skillW() { cout 英雄 A 释放了 E 技能 endl; }void skillE() { cout 英雄 A 释放了 W 技能 endl; }void skillR() { cout 英雄 A 释放了 R 技能 endl; } }; ​ class B : public Hero { public:void skillQ() { cout 英雄 B 释放了 Q 技能 endl; }void skillW() { cout 英雄 B 释放了 E 技能 endl; }void skillE() { cout 英雄 B 释放了 W 技能 endl; }void skillR() { cout 英雄 B 释放了 R 技能 endl; } }; ​ class C : public Hero { public:void skillQ() { cout 英雄 C 释放了 Q 技能 endl; }void skillW() { cout 英雄 C 释放了 E 技能 endl; }void skillE() { cout 英雄 C 释放了 W 技能 endl; }void skillR() { cout 英雄 C 释放了 R 技能 endl; } }; ​ int main() {int option 0;cout 请选择英雄1-A2-B3-C;cin option; ​if (option 1){A a;a.skillQ();a.skillW();a.skillE();a.skillR();}else if (option 2){B b;b.skillQ();b.skillW();b.skillE();b.skillR();}else if (option 3){C c;c.skillQ();c.skillW();c.skillE();c.skillR();}return 0; } 但是使用多态可以让编程更方便代码更精简 #include iostream using namespace std; ​ class Hero { public:virtual void skillQ() { cout 英雄释放了 Q 技能 endl; }virtual void skillW() { cout 英雄释放了 E 技能 endl; }virtual void skillE() { cout 英雄释放了 W 技能 endl; }virtual void skillR() { cout 英雄释放了 R 技能 endl; } protected:int HP;  // 体力值、血量int MP;  // 魔法值int AD;  // 物理伤害int AP;  // 法术伤害 }; ​ class A : public Hero { public:virtual void skillQ() { cout 英雄 A 释放了 Q 技能 endl; }virtual void skillW() { cout 英雄 A 释放了 E 技能 endl; }virtual void skillE() { cout 英雄 A 释放了 W 技能 endl; }virtual void skillR() { cout 英雄 A 释放了 R 技能 endl; } }; ​ class B : public Hero { public:virtual void skillQ() { cout 英雄 B 释放了 Q 技能 endl; }virtual void skillW() { cout 英雄 B 释放了 E 技能 endl; }virtual void skillE() { cout 英雄 B 释放了 W 技能 endl; }virtual void skillR() { cout 英雄 B 释放了 R 技能 endl; } }; ​ class C : public Hero { public:virtual void skillQ() { cout 英雄 C 释放了 Q 技能 endl; }virtual void skillW() { cout 英雄 C 释放了 E 技能 endl; }virtual void skillE() { cout 英雄 C 释放了 W 技能 endl; }virtual void skillR() { cout 英雄 C 释放了 R 技能 endl; } }; ​ int main() {int option 0;cout 请选择英雄1-A2-B3-C;cin option; ​Hero* p nullptr;if (option 1)p new A;else if (option 2)p new B;else if (option 3)p new C; ​if (p){p-skillQ();p-skillW();p-skillE();p-skillR();delete p;}return 0; } 二、协变和如何析构派生类对象 2.1 - 协变 协变就是在派生类中重写基类虚函数时基类虚函数的返回值类型为基类对象的指针或引用派生类虚函数的返回值类型为派生类对象的指针或引用。 协变是虚函数重写的一种例外。 class A {}; ​ class B : public A {}; ​ class Person { public:virtual A* func() { return new A; } }; ​ class Student : public Person { public:virtual B* func() { return new B; } }; 2.2 - 如何析构派生类对象 用基类指针指向派生类对象是多态的精髓但是如果用基类指针销毁派生类对象的时候不能调用派生类的析构函数就可能会造成内存泄漏因为在应用开发中我们一般会把释放资源的代码写在析构函数中例如释放堆区申请的内存空间。 #include iostream using namespace std; ​ class Person { public:~Person() { cout ~Person() endl; } }; ​ class Student : public Person { public:~Student() { cout ~Student() endl; } }; ​ int main() {Person* pp new Person;delete pp;  // ~Person() ​pp new Student;delete pp;// ~Person() -- 说明没有调用派生类的析构函数return 0; } 不过解决方法很简单只要把基类的析构函数设置为虚函数然后在派生类中重写基类的虚函数即可。 但问题是基类和派生类的析构函数的函数名是不可能相同的违背了虚函数重写的规则答案则是 C 编译器对它们的名称做了特殊的处理编译后统一处理成 destructor。 #include iostream using namespace std; ​ class Person { public:virtual ~Person() { cout ~Person() endl; } }; ​ class Student : public Person { public:virtual ~Student() { cout ~Student() endl; } }; ​ int main() {Person* pp new Person;delete pp;  // ~Person() ​pp new Student;delete pp;// ~Student()// ~Person()return 0; } 三、C11 的 override 和 final 关键字 C11 的 override 和 final 关键字能让我们的程序在继承类和重写虚函数时更安全以及更清晰。 override 关键字可以让编译器检查我们在派生类中重写的基类的虚函数是否正确 class Person { public:virtual void func() const { cout hello world~ endl; }; }; ​ class Student : public Person { public:virtual void func() override { cout 你好世界~ endl; }; }; 这是因为我们在派生类中重写基类的虚函数时忘记加 const 了。 final 关键字则可以防止派生类重写基类的虚函数 class Person { public:virtual void func() const final { cout hello world~ endl; } }; ​ class Student : public Person { public:virtual void func() const { cout 你好世界~ endl; } };
http://www.w-s-a.com/news/268410/

相关文章:

  • 卓训网是个什么网站wordpress命令执行时间
  • 网站建设需要做哪些工作网片焊接
  • 网站优化方案dedecms win8风格网站模板
  • 企业如何制作网站管理系统慈溪住房和城乡建设部网站
  • 青岛网站建设有哪些公司区块链网站开发价格
  • 怎么设置网站的logo微信公众号的h5网站开发6
  • 粉色的网站绍兴市建设局网站
  • 个人网站的基本风格是wordpress 模板选择
  • 南昌专业做网站公司有哪些广州市住房城乡建设部门户网站
  • 福州网站建设团队淘宝联盟网站怎么建设
  • 福州企业网站建站模板国内黑色风格的网站
  • 好看的网站首页设计android移动开发
  • 域名注册完成后如何做网站域名 删除 wordpress
  • wordpress xml导入大小东莞seo优化方案
  • 网站建设效益网站销售怎么做的
  • 利用网站空间做代理设计方案的格式范文
  • 无锡建设工程质量监督网站遵义做手机网站建设
  • 衡阳商城网站制作ps做网站首页规范尺寸
  • 微信网站应用开发营销推广的方案
  • 广州做网站商城的公司制作一个app的完整流程
  • 湖南城乡建设厅网站163注册企业邮箱
  • 做网站怎么调整图片间距织梦做的网站如何去掉index
  • 凡科网免费建站步骤及视频网页设计基础教程第二版课后答案
  • 建设一个旅游网站毕业设计企业网站要更新文章吗
  • 做网站需要简介中山网站设计公司
  • 网站怎么做导航栏微信公众号官网登录
  • 1_ 掌握网站开发的基本流程 要求:熟悉网站开发与设计的基本流程.电子商城网站开发
  • 百度网站怎么建设河北省工程造价信息网官网
  • 阿里云网站模板网页设计的合适尺寸是多少
  • 做小程序和做网站哪个好让别人做网站推广需要多少钱