这篇文章主要介绍了C++继承与菱形继承怎么定义的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++继承与菱形继承怎么定义文章都会有所收获,下面我们一起来看看吧。继承机制是面向对象程序设计的一种实现代码复用的重要手段,它允许程序员在保持原有类特性的基础上进行拓展,增加其他的功能,在此基础上也就产生了一个新的类,称为派生类。继承呈现了面向对象程序设计的层次结构,是类设计层次的复用。继承的格式在前面的例子中,person是基类,student是派生类,继承方式是public. 这是很容易记忆的,person是基础的类,student是在person这个类的基础之上派生出来的。这就非常地像父子关系,所以基类又可以称为父类,派生类又可为子类。子类的后面紧跟着:
,是:
后面这个类派生出来的。继承关系和访问限定符继承的几种方式和访问限定符是相似的。三种继承方式:public继承、protected继承、private继承。三种访问限定符:public访问、protected访问、private访问。基类类成员的访问权限和派生类继承基类的继承方式, 关系到了基类被继承下来的类成员在派生类中的情况。ps:这句话起始很好理解地,就是这句话写起来就变得绕口和复杂了,哈哈哈????.这里的不可见指的是:基类中的private成员也是被继承下来了的,只是在语法上,在派生类的类里和类外都不能够访问。记住这个特殊的点,那么其他的就可理解为“权限问题”,这里“权限只能缩小,不能放大”。例如,基类的public成员以private继承方式继承下来,为“权限小的那个”,也就是继承下来后在派生类中是private成员。派生类的对象可以赋值给其基类的对象、基类的指针、基类的引用。就像上面这样,取基类需要被赋值的值过去即可。派生类赋值给基类的对象、基类的指针、基类的引用。在派生类中取基类需要的,就像把派生类给切割了一样、所以这里有一个形象的称呼:切割/切片【注意】1、不允许基类对象赋值给派生类对象2、允许基类指针赋值给派生类指针, 但是需要强制转化。这种转化虽然可以,但是会存在越界访问的问题。基类和派生类都有独立的作用域。继承下来的基类成员在一个作用域,派生类的成员在另一作用域。基类中有一个_num 给了缺省值“12138”, 派生类中也有一个_name,给了缺省值“52622”,那么在派生类里直接使用_name,使用的具体是哪一个类里的?使用的是派生类Student里的。总结:基类和派生类中如果有同名成员,派生类将屏蔽基类对同名成员的直接访问,这种情况称为隐藏 , 或者称为重定义。如果想要访问,则使用基类::基类成员
显示的访问。运行结果我们已经了解了什么是隐藏。那么来看一下下面这些代码。函数重免费云主机域名载要求在同一作用域,而被继承下来的基类成员和派生类成员在不同的作用域,所以构成的是隐藏。因为func()
函数隐藏了,在派生类的作用域内没有func()
函数,所以会出现编译报错。类有8个默认成员函数,这里只说重点的四个默认成员函数:构造函数、析构函数、拷贝构造函数、赋值重载函数如果我们不写派生类的构造函数和析构函数,编译器会做如下的事情:1、基类被继承下来的部分会调用基类的默认构造函数和析构函数2、派生类自己也会生成默认构造和析构函数,派生类自己的和普通类的处理一样如果我们不写派生类的赋值构造函数和拷贝构造函数,编译器会做如下的事情3、基类被继承下来的部分会调用基类的默认拷贝构造函数和赋值构造函数。4、派生类自己也会生成默认赋值拷贝构造函数和赋值函数,和普通类的处理一样。什么情况下需要自己写?1、父类没有合适的默认构造函数,需要自己显示地写2、如果子类有资源需要释放,就需要自己显示地写析构函数3、如果子类存在浅拷贝的问题,就需要自己实现拷贝构造和赋值函数解决浅拷贝的问题。如果需要自己写派生类的这几个重点成员函数,那么该如何写?1、实现派生类的构造函数:需要调用基类的构造函数初始化被继承下来的基类部分的成员。如果基类没有合适的默认构造函数,就需要在实现派生类构造函数的初始化列表阶段显示调用。2、实现派生类的析构函数:派生类的析构函数会在被调用完成后自动调用基类的析构函数清理被继承下来的基类成员。这样可以保证派生类自己的成员的清理先于被继承下来的基类成员。ps:析构函数名字会被统一处理成destructor()
,所以被继承下来的基类的析构函数和派生类的析构函数构成隐藏。3、实现派生类的拷贝构造函数:需要调用基类的拷贝构造函数完成被继承下来的基类成员的拷贝初始化。4、实现派生类的operator=:需要调用基类的operator=完成被继承下来的基类成员的赋值。5、派生类对象初始化先调用基类构造再调用派生类构造。继承可分为单继承和多继承。单继承:一个派生类只有一个直接基类多继承:一个派生类有两个或两个以上的直接基类。而多继承中又存在着一种特殊的继承关系,菱形继承它们之间的继承关系逻辑上就类似一个菱形,所以称为菱形继承。菱形继承相对于其他继承关系是复杂的。B中有一份A的成员,C中也有一份A的成员,D将B和C都继承了,那么D中被继承下来的A的成员不就有两份了吗?不难看出,菱形继承有数据冗余和二义性的问题。上面的继承关系如下:此时Assitant中有两份_name.存在数据冗余和二义性的问题。二义性的问题是比较好解决的,使用::
指定就可以了,但是并不能解决数据冗余的问题。虚拟继承可以解决继承的数据冗余和二义性的问题。如上面所画的逻辑继承关系。在开始可能产生数据冗余和二义性的地方使用虚拟继承,即可解决,但是在其他地方不要去使用虚拟继承。虚拟继承格式虚拟继承解决数据冗余和二义性的原理为了更好地研究,在这里给出一个比较简单的菱形继承体系B和C中都有一份A的数据可以看出数据的冗余。现在增加虚拟继承机制,解决数据冗余和二义性。再次调式调用内存窗口,会发现和没有采用虚拟继承的内存窗口有较大的变化。B中的地址0x00677bdc里有什么?C中的地址0x00677be4里有什么?从内存窗口可看出,菱形虚拟继承,内存中只在对象组成的最高处地址保存了一份A,A是B、C公共的。而B和C里分别保存了一个指针,该指针指向一张表。这张表称为虚基表,而指向虚基表的指针称虚基指针。虚基表中保存的值,是到A地址的偏移量,通过这个偏移量就能够找到A了。在没有学习继承之前,我们其实频繁地使用组合。继承是一种is-a的关系, 每一个派生类是基类,例如,Student是一个Person, Teacher 是一个Person组合是一种has-a的关系,Person组合了head, hand, 每一个Person对象中都有一个head、hand对象。如果某种情况既可以使用继承又可以使用组合,那么优先使用对象组合,而不是类继承。友元关系不能被继承,好比父亲的朋友不一定是你的朋友。如果基类中定义了静态成员,当这个基类被实例化后出现了一份,那么整个继承体系中都只有这一份实例。关于“C++继承与菱形继承怎么定义”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C++继承与菱形继承怎么定义”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注百云主机行业资讯频道。
这篇文章主要介绍“ASP.NET中加密和解密怎么实现”,在日常操作中,相信很多人在ASP.NET中加密免费云主机域名和解密怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ASP.NET中加密和解密怎么实现”的疑惑有所帮助!…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。