赋值兼容规则(C++)
admin
2023-02-15 01:40:05
0

在一定条件下,不同类型的数据之间可以进行类型转换,如可以将整型数据赋给双精度型变量。在赋值之前,先把整型数据转换成双精度型数据,然后再把它赋给双精度型变量。这种不同类型数据之间的自动转换和赋值,称为赋值兼容。在基类和派生类对象之间也存有赋值兼容关系,基类和派生类对象之间的赋值兼容规则是指在需要基类对象的任何地方,都可以使用其子类对象来代替。

下面主要讲积基类和派生类对象之间的赋值兼容
派生类的对象可以赋值给基类对象。

   A a1; //定义基类A对象a1
   B b1; //定义类A的公用派生类B的对象b1
   a1=b1; //用派生类B对象b1对基类对象a1赋值

  在赋值时舍弃派生类自己的成员,只进行数据成员的赋值。

  实际上,所谓赋值只是对数据成员赋值,对成员函数不存在赋值问题,内存中数据成员和成员函数是分开的。

 注意: 赋值后不能企图通过对象a1去访问派生类对象b1的成员,因为b1的成员与a1的成员是不同的。  

假设age是派生类B中增加的公用数据成员,分析下面的用法:

  a1.age=23;//错误,a1中不包含派生类中增加的成员
b1.age=21; //正确,b1中包含派生类中增加的成员

只能用子类对象对其基类对象赋值,而不能用基类对象对其子类对象赋值,理由是显然的,两种对象的大小是不同的,因为基类对象不包含派生类的成员无法对派生类的成员赋值。同理,同一基类的不同派生类对象之间也不能赋值
赋值兼容规则(C++)
2·派生类的对象可以初始化基类的引用。
已定义了基类A对象a1,可以定义a1的引用变量:

    A a1; //定义基类A对象a1
    B b1; //定义公用派生类B对象b1
    A &r=a1; //定义基类A对象的引用变量r(A的别名是r),并用a1对其初始化

这时,r和a1共享同一段存储单元。也可以用派生类对象初始化引用变量r,将上面最后一行改为

A& r=b1;//定义基类A对象的引用变量r,并用派生类B对象b1//对其初始化

注意: 此时r并不是b1的别名,也不与b1共享同一段存储单元。它只是b1中基类部分的别名

这里的r定义为A类的引用,所以它的有效范围就只有A类那么大,r与b1中基类部分共享同一段存储单元,r与b1具有相同的起始地址。 
如果函数的参数是基类对象或基类对象的引用,相应的实参可以用子类对象。
3·派生类对象的地址可以赋给指向基类的指针。也就是说,指向基类对象的指针变量也可以指向派生类对象。
例定义一个基类Student(学生),再定义Student类的公用派生类Graduate(研究生), 用指向基类对象的指针输出数据。

#include 
#include 

using namespace std;
class Student//声明Student类
{
   public :
   Student(int, string,float );//声明构造函数
   void display( );//声明输出函数
   private :
   int num;
   string name;
   float score;
};
Student::Student(int n, string nam,float s)  //定义构造函数
{
   num=n;
   name=nam;
   score=s;
}
void Student::display( )//定义输出函数
{
   cout<display( ); //调用stud1.display函数
   pt=&grad1; //指针指向grad1
   pt->display( ); //调用grad1.display函数
}

很多读者会认为: 在派生类中有两个同名的display成员函数,根据同名隐藏的规则,被调用的应当是派生类Graduate对象的display函数,
在执行Graduate::display函数过程中调用Student::display函数,输出num,name,score,然后再输出pay的值。

事实上这种推论是错误的,先看看程序的输出结果:

num:1001
name:Li
score:87.5
num:2001
name:wang
score:98.5
并没有输出pay的值。

问题在于pt是指向Student类对象的指针变量,它的指类是Student类,即使让它指向了grad1,但实际上pt指向的是grad1中从基类继承的部分(它指向的空间只能是基类中数据成员那么大的空间)。通过指向基类对象的指针,只能访问派生类中的基类成员,而不能访问派生类增加的成员。所以pt->display()调用的不是派生类Graduate对象所增加的display函数,而是基类的display函数,所以只输出研究生grad1的num,name,score3个数据。

其实,通过强制转换也可以将Student类的地址赋值给Graduate类所定义的指针,但是,这样做不安全,会让使用者误以为可以调用Graduate类中增加的成员,其实不然,所以不建议使用

综上所述,主要是因为基类和派生类中成员所占空间大小的不同,所引发的赋值兼容问题,例如int类型赋值给double类型,就是赋值兼容问题,而double类型赋值给int类型,就是不兼容,必须要强转,不然会报错

原文链接:https://blog.csdn.net/ilovekobemusic/article/details/8839371

相关内容

热门资讯

中美频繁高层互动,菲律宾好自为... 7月24日,菲律宾组织7艘公务船、3艘海警舰、1艘运鱼船,并唆使大量渔船位中国黄岩岛管辖海域非法聚集...
被要求补税2250万欧元的法国... ·贝尔纳·阿尔诺。(LVMH官网)他的“帝国”离不开这个国家的形象加持,而这个国家,也早已吃定了这一...
通派龙湖御潮云上:当极核地段遇... 在2026年的郑州楼市版图中,如果要寻找一个能够同时承载“主城确定性”与“产品革新力”的坐标,通派龙...
追光引路人—记国家级线上线下混... 人物名片:吴建丽,教授,黄河科技学院医学部教师。主持国家级线上线下混合式一流课程1门、河南省线上线下...
加总理表态:若谈判破裂,会对美... 据凤凰卫视报道,7月23日,加拿大总理卡尼与各省省长和地区领导人举行会议,商讨应对美国最新一轮关税威...
从北京望中东:和平,虽远在中国... ◆笔者参与的分论坛“维护中东和平:挑战与出路”正在进行中。今年7月举行的第十四届世界和平论坛上,中东...
巨大冲击!美国AI“闭源高价售... 日本计算机社会学专家塚越健司7月24日发表题为《中国AI“Kimi K3”引发巨大冲击——撼动美国A...
人民锐评:中国籍数学家首获全球... 历史性的突破!日前,第二十一届菲尔兹奖得主名单揭晓,北大2007级本科校友王虹、邓煜双双获奖,无数网...
深度专访|网易智企段毓铮:不敢... 企业AI的商业化,难点在于让客户敢用、会用、用得有效果。在WAIC现场,搜狐AI邀请到网易智企副总经...
来论|从“菲尔兹奖”,看见科技... 王虹、邓煜分别凭借在调和分析与几何测度论、偏微分方程与数学物理领域的突破性工作,共同荣获2026年菲...