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

绿韵建设有限公司网站合肥制作网站的公司

绿韵建设有限公司网站,合肥制作网站的公司,经典模板网站建设,动漫网站的建设目标目录 一#xff0c;概念 二#xff0c;继承定义 1. 继承格式 2. 访问限定符与继承方式的关系 3. 继承父类成员访问方式的变化 小结#xff1a; 三. 父类与子类对象赋值转化 四#xff0c;继承作用域 1.特点 2. 测试题 五#xff0c;派生类不一样的默认成员函…目录 一概念 二继承定义 1. 继承格式  2. 访问限定符与继承方式的关系 3. 继承父类成员访问方式的变化 小结  三. 父类与子类对象赋值转化 四继承作用域 1.特点  2. 测试题 五派生类不一样的默认成员函数 1.构造函数 2.拷贝构造 3.赋值符号重载 4.析构函数 5. 小结 六友元与继承 七继承与静态成员 2.思考如何制作一个无法被继承的类 八菱形继承与虚拟菱形继承 1. 菱形继承的问题 2. 虚拟继承解决方案 3. 虚拟继承底层细节  九继承与组合 总结 结语 一概念 继承(inheritance)机制是面向对象程序设计 使代码可以复用的最重要的手段它允许程序员在 保持原有类特性的基础上进行扩展增加功能这样产生新的类称派生类。继承 呈现了面向对象程序设计的层次结构体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用 继承是类设计层次的复用。 基于原有类的一般叫做基类(base_class)我感觉叫他为—— 父类 这更容易理解。 运行下面代码 #include iostream #include stringusing namespace std;class Person { public:void Print(){cout name: _name endl;cout age: _age endl;} protected:string _name peter; // 姓名int _age 18; };class Student : public Person { protected:int _stuid; // 学号 };class Teacher : public Person { protected:int _jobid; // 工号 };int main() {Student s;Teacher t;s.Print();t.Print();t.Print();return 0; } 继承后父类的Person的成员成员函数成员变量都会变成子类的一部分。这里体现出了Student和Teacher复用了Person的成员。下面我们使用监视窗口查看Student和Teacher对象可以看到变量的复用。调用Print可以看到成员函数的复用。 二继承定义 1. 继承格式  下面我们看到Person是父类也称作基类。 Student是子类也称作派生类   2. 访问限定符与继承方式的关系 使用关键字class时默认的继承方式是private使用struct时默认的继承方式是public不过最好显示的写出继承方式。 3. 继承父类成员访问方式的变化 小结  1. 父类private成员在派生类中无论以什么方式继承都是不可见的。这里的 不可见是指父类的私有成员还是被继承到了派生类对象中但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。 2. 父类private成员在派生类中虽然被继承了但父类私有是不可见的因为权限问题如果父类成员不想在类外直接被访问但需要在派生类中能访问就定义为protected。 可以看出保护成员限定符是因继承才出现的。 3. 子类访问权限    修饰符与继承方式的最小权限 如修饰符是private,继承方式是public最终权限是private。 权限从大到小是public protected private 4.在实际运用中一般使用都是public继承几乎很少使用protetced/private继承也不提倡使用protetced/private继承因为protetced/private继承下来的成员都只能在派生类的类里面使用实际中扩展维护性不强。所以基本上常用的处理 继承方式public。 处理成员变量函数: 用public / protected 三. 父类与子类对象赋值转化 子类对象 可以赋值给 父类的对象 / 父类的指针 / 父类的引用。这里有个形象的说法叫 切片或者 切割。寓意把派生类中父类那部分切来赋值过去。 class Person { protected:string _name; // 姓名string _sex;int _age; // 年龄 }; class Student : public Person { public:int _No; // 学号 };void Test() {Student sobj;// 1.子类对象可以赋值给父类对象/指针/引用Person pobj sobj;Person* pp sobj;Person rp sobj;//2.父类对象不能赋值给子类对象// sobj pobj;// 3.父类的指针可以通过强制类型转换赋值给子类的指针pp sobj;Student * ps1 (Student*)pp; // 这种情况转换时可以的。ps1-_No 10;// 父类利用指针强转给子类指针pp pobj;Student* ps2 (Student*)pp; // 这种情况转换时虽然可以但是会存在越界访问的问题ps2-_No 10; }我们可以发现 1. 父类对象不能赋值给子类对象 2. 父类对象地址强转为子类地址最终在子类访问其新成员时会发生越界报错。 四继承作用域 1.特点  1. 在继承体系中 基类和 派生类都有 独立的作用域。(所以即使父子类有同名函数因不在同一作用域则不叫做函数重载) 2. 子类和父类中有同名成员 子类成员将屏蔽父类对同名成员的直接访问这种情况叫 隐藏 也叫重定义。在子类中可以 使用 基类::基类成员显示访问父类成员 3. 需要注意的是如果是成员函数的隐藏只需要 函数名相同就构成隐藏。 4. 注意在实际中在 继承体系里面最好 不要定义同名的成员。 2. 测试题 class A { public:void fun(int i){cout func() endl;} };class B : public A { public:void fun(int i){A::fun();cout func(int i)- i endl;} }void Test() {B b;b.fun(); }; // 不定向选择 // A: 子父func构成重载 // B: 子父func构成隐藏 // C: 程序报错 // D以上都不对 答案BC 。B,首先是子父类拥有同名成员函数构成隐藏。C因为子类对父类同名函数的隐藏导致无法找到匹配fun函数因此报错。 五派生类不一样的默认成员函数 这是本次的实验代码经过这次的学习我们来补充这个派生类。 class Person { public:Person(const char* name peter): _name(name){cout Person() endl;}Person(const Person p): _name(p._name){cout Person(const Person p) endl;}Person operator(const Person p){cout Person operator(const Person p) endl;if (this ! p)_name p._name;return *this;}~Person(){cout ~Person() endl;} protected:string _name; // 姓名 };class Student : public Person { public:// 构造函数 protected:int _num; //学号 };void Test() {Student a;int x 1; }int main() {Test();return 0; } 1.构造函数 我们先不写构造函数我们查看默认构造函数会发生什么事 很明显默认构造函数父类会调用其自己的构造函数子类也是调用其自己的构造函数没有则编译器自动生成构造函数。总之各自构造各自的且构造顺序为先父类——子类。 // 构造函数Student(const char* name ,const int num 0):Person(name),_num(num){} 2.拷贝构造 思路父类数据通过父类的隐式转化。 // 拷贝构造Student(const Student s1):_num(s1._num), Person(s1) // 通过子类向父类的强转化{cout Student(const Student ) endl;} 3.赋值符号重载 思路调用父类赋值符号重载再给子类成员变量赋值。 // 赋值符号重载Student operator(const Student s1){cout operator endl;if (this ! s1){Person::operator(s1);_num s1._num;} return *this;} 补充如果子类成员变量不需要深拷贝其实不需要写拷贝赋值符号重载函数因为父类有这两个函数。 4.析构函数 这个没啥好说的父子类各自调用各自的析构函数。 析构顺序子类先析构当子类析构完成后再调用父类析构。 5. 小结 1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数则必须在派生类构造函数的初始化列表阶段显示调用。 2. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。 3. 派生类的operator 必须要调用基类的operator完成基类的复制。 4. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。 5. 派生类对象初始化先调用基类构造再调派生类构造。 6. 派生类对象析构清理先调用派生类析构再调基类的析构。 7. 因为后续一些场景析构函数需要构成重写重写的条件之一是函数名相同(这个我们后面会讲 解)。那么编译器会对析构函数名进行特殊处理处理成destrutor()所以父类析构函数不加virtual的情况下子类析构函数和父类析构函数构成隐藏关系。 六友元与继承 如果大家对友元陌生了可以看小博主这篇文章回忆详解C类和对象下篇——用代码实践功能_花果山~~程序猿的博客-CSDN博客 结论派生类不能继承父类的友元关系换句话说友元函数或者友元类无法直接获取派生类的私有或者保护成员变量及函数。   示例代码  class Student; class Person { public:friend void Display(const Person p, const Student s); protected:string _name; // 姓名 }; class Student : public Person { protected:int _stuNum; // 学号 }; void Display(const Person p, const Student s) {cout p._name endl;cout s._stuNum endl; } void main() {Person p;Student s;Display(p, s); } 友元关系无法继承所以在派生类中如果需要友元关系需要重新声明友元关系。  七继承与静态成员 静态成员变量与函数相关基础知识详解C类和对象下篇——用代码实践功能_花果山~~程序猿的博客-CSDN博客 现象结论基类定义了static静态成员则整个继承体系里面只有一个这样的成员。无论派生出多少个子类都只有一个static成员实例 。 示例代码: class Person { public:Person() { _count; } protected:string _name; // 姓名 public:static int _count; // 统计人的个数。 };int Person::_count 0;class Student : public Person { protected:int _stuNum; // 学号 };class Graduate : public Student { protected:string _seminarCourse; // 研究科目 };void TestPerson() {Student s1;Student s2;Student s3;Graduate s4;cout Person接口 人数 : Person::_count endl;Student::_count 666; // 在Student类访问Person类中静态成员变量并且设置该静态成员变量cout Person接口 人数 : Person::_count endl;cout Student接口 人数 : Student::_count endl;cout Graduate接口 人数 : Graduate::_count endl; }2.思考如何制作一个无法被继承的类 思路对构造与析构函数其中一个私有化。 class Person { public:~Person() {} private:Person(){}int _age -1;char* _name; };class Student : public Person { private:int _score; };void TestPerson() {Student a;Person a1; // 当然父类自己也实例不了对象了 } 诺这样子类就调不动父类。但同时父类自己也实例不了对象你真的哭死我了。 解决方案创建一个静态成员函数让类外就可以实例化对象这样就绕开了创建对象时系统调用构造函数这条路。 // 单纯的成员函数也不行因为对象都没有你告诉咋调函数。static Person create_Person(){return Person();} 八菱形继承与虚拟菱形继承 1. 菱形继承的问题 从下面的对象成员模型构造可以看出菱形继承有 数据冗余 和 二义性 的问题。 在 Assistant 的对象中 Person 成员会有两份。这会 导致内存浪费 2. 虚拟继承解决方案 虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系在 Student 和 Teacher 的继承 Person 时使用虚拟继承即可解决问题。需要注意的是虚拟继承不要在其他地 方去使用。 实验代码 class A { public:int _a; };// class B : public A class B : virtual public A { public:int _b; };// class C : public A class C : virtual public A { public:int _c; };class D : public B, public C { public:int _d; };int main() {D d;d.B::_a 1;cout (d.B::_a) endl;d.C::_a 2;cout (d.C::_a) endl;d._b 3;d._c 4;d._d 5;return 0; } 虚拟菱形继承让一个类通过虚拟继承从多个基类继承时只会保留一个共同的基类子对象避免了出现多个相同的基类子对象。 诺数据冗余 3. 虚拟继承底层细节  这里可以分析出D对象中将A放到的了对象组成的最下面这个A同时属于B和C那么B和C如何去找到公共的A呢 这里是通过了 B 和 C 的两个指针指 向的一张表。这 两个指针 叫虚基表指针这两个表叫 虚基表 。虚基表中存的偏移量。通过偏移量 可以找到下面的 A 。  这里会提到内存大小端知识可以参见本文【C语言】整浮点型数据存储大小端。细节拉满_小端浮点数组_花果山~~程序猿的博客-CSDN博客 原理精简图 补充如果多个相同虚拟菱形继承类的对象其访问的偏移表是同一套。如D是一个虚拟菱形继承的类则D   d1, d2, d3....., d1,d2,d3都是访问同一套偏移表。从这里我们也可以发现虚拟菱形继承为了解决数据冗余和二义性的问题需要访问偏移表但毫无疑问这会造成性能损失。 九继承与组合 继承是一种关系其中一个类称为子类或派生类可以继承另一个类称为父类或基类的属性和方法。 组合是另一种关系其中一个类称为容器类包含另一个类的对象称为成员类。容器类通过创建成员类的对象来使用成员类的属性和方法。 就像之前我们所学的STL中vector类这样的容器里面放着string类 总结 1. 继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言在继承方式中基类的内部细节对子类可见 。继承一定程度破坏了基类的封装基类的改变对派生类有很大的影响。 派生类和基类间的依赖关系很强耦合度高。 2. 对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse)因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组 合类之间没有很强的依赖关系耦合度低。优先使用对象组合 有助于你保持每个类被封装。 3.实际尽量 多去用组合。组合的耦合度低代码维护性好。不过继承也有用武之地的有些关系就适合继承那就用继承另外要实现多态也必须要承。类之间的关系可以用继承 可以用组合就用组合。 结语 本小节就到这里了感谢小伙伴的浏览如果有什么建议欢迎在评论区评论如果给小伙伴带来一些收获请留下你的小赞你的点赞和关注将会成为博主创作的动力
http://www.huolong8.cn/news/199091/

相关文章:

  • 网站开发 8g和16g网站蓝色导航栏代码
  • 国内做服装的网站有哪些方面无锡网络建站
  • 自助建站还是人工建站好网页制作基本步骤
  • 网站导航界面石家庄关键词搜索引擎优化
  • 广东省建设监理协会网站 首页做网站标题图片大小
  • 网站开发的职位要求做体育类网站素材
  • 镇平建设局网站自己做的网站怎么管理用户
  • 如何建立公司网站建议和规则网站布局模板
  • 网站建设规划范文中国制造网入驻
  • 婚庆网站开发的意义vue做网站cms
  • 做个公司网站win10优化工具
  • 网站搭建平台wordpress首页添加js
  • 虚拟主机控制面板怎么建设网站谁分享一个免费网站2021
  • 国内做网站最大的公司有哪些网站展示模板psd下载
  • 6入空间网站免费观看简述电子商务的含义
  • 郑州网站推广技术南皮哪有做网站的
  • 怎么做中英文网站网页游戏排行傍
  • 潮汕17网站一起做网店官网广州自助网站设计平台
  • 做盗版电影网站后果网址地址
  • 运城推广型网站开发兰州新站点seo加盟
  • 湖南住房和城乡建设厅网站首页阿里云配置网站
  • 潜江seo大连seo外包
  • 东营建设企业网站公司网址怎么注册步骤
  • 建网站资料温州网络科技技术有限公司
  • 三门峡企业网站建设公司重庆医院门户网站建设
  • 网站开发与兼容模式搜索引擎优化涉及的内容
  • 怎么做刷业网站成都网站建设服务功能
  • 商丘网站制作公司一二三网络推广关于企业网站建设的建议
  • 学习做网站要多久美丽乡村建设网站
  • 在阿里巴巴上做网站有效果吗成都市青羊区城乡建设局网站