虚基类的声明是用在指定派生类时,放在派生类名的后面。该指针被称为虚基类指针。解:上述程序中,各类之间构成类层次如图6.14所示,其中虚线表示是虚继承,也就是说,其基类为虚基类。......
2023-11-07
因为派生类对象也是基类对象,所以指向派生类对象的指针可以转换为指向基类对象的指针,这种引用方式是安全的,但是用这种方式只能引用基类成员。如果试图通过基类指针引用那些只有在派生类中才有的成员,编译系统会报告错误。例如,声明一个基类A和派生类B:
class A
{…};
class B:A
{};
以下语句先定义了基类A的对象指针p和派生类B的对象b,并通过p指向b:
A*p;
B b;
p=&b
派生类对象可以由基类指针所指向,这是从派生类到基类的映射,在类层次图中是上升的,所以称之为向上映射。
例如,有以下程序:
上述程序的main函数中,p定义为指向基类A对象的指针变量,它不仅可以指向基类A对象a,也可以指向派生类对象b,并通过p->dispa()执行基类A的成员函数,但即使p指向对象b,也不能执行p->dispb()。本程序执行结果与上一个例子的结果完全相同。
为了更明确这种向上映射转换,C++提供了dynamic_cast运算符,其使用格式如下:
dynamic_cast(类型>(表达式)(www.chuimin.cn)
其功能是将“表达式”转换成“类型”指定的对象,“类型”必须是以前定义类的一个指针或引用。例如:
前面的程序中,可以把p=&b;语句改为:
p=dynamic_cast<A*>(&b);
尽管不影响程序的正确性,但这样改动后程序更加清晰。
需要注意的是,基类指针虽然获取了派生类对象的地址,但只能访问派生类从基类继承的成员,不能访问派生类中新增的成员,除非对基类指针强制类型转换调用派生类的成员函数。例如,若将上述程序中的主函数改为:
这样,程序会执行错误,但采用基类指针强制类型转换,主函数改为:
这样,程序能够正确执行,但由于a对象中没有给y成员赋值,所以第一次调用dispb()结果输出没有意义的y值。
【例6.10】编写一个程序,将大学生和研究生的分数转换成对应的等级并输出。
解:设计一个学生类Stud,其中包含一个公有成员函数disp()用于将学生的分数转换成对应的等级并输出。由Stud类派生出大学生类Unstud和研究生类Grstud。对应的程序如下:
程序执行结果如下:
张大明76中
刘晓华85良
有关C++程序设计基础教程的文章
虚基类的声明是用在指定派生类时,放在派生类名的后面。该指针被称为虚基类指针。解:上述程序中,各类之间构成类层次如图6.14所示,其中虚线表示是虚继承,也就是说,其基类为虚基类。......
2023-11-07
类的每一个成员函数都有一个隐含的特殊指针,通常称为this指针,this指针的类型就是成员函数所属的类型。通常不显式使用this指针。this指针是C++实现封装的一种机制,它将对象和该对象调用的成员函数连接在一起,在外部看来,每个对象都拥有自己的成员函数。this指针一般用于返回当前对象自身。程序的执行结果如下:s1∶n=2s2∶n=1s3∶n=3this指针大量用于运算符重载成员函数设计中,这将在后面详细介绍。......
2023-11-07
图2.3对象stu1和stu2实际上,类Student的所有成员函数放在公用区中,每个函数代码有一个地址,类Student的每个对象中只存放自己的数据成员值和指向公共区中对应函数的地址,也就是说,类的成员函数是共享的,如图2.4所示,这种对象的存储空间分配方式不仅节省了存储空间,而且各个对象的数据成员分别存放,互不相干。......
2023-11-07
指针初始化有几种方式:指针对象可以被一个具有相同类型的对象初始化。下面的例子将整型指针ip赋给另一整型指针ip2:int*ip2=ip;此时,这两个指针指向同一内存空间,可用图1.8表示。图1.8指针与指针所指对象如果程序员想强制赋给指针另一种类型变量的地址,则必须显式进行类型转换。如要将一个整型指针的值赋给浮点数指针,可以采用以下语句:float*fp=ip;通过直接分配内存地址得到初值。......
2023-11-07
在C++中,数组和指针密切相关,几乎可以互相使用。数组名字可以认为是常量指针,它指向存放数组第一个元素的内存地址。指针可以用于完成任何涉及数组下标的操作。实际上,数组下标表示法在编译期间将转换为指针表示法,所以用指针方式来书写数组下标表达式可以节省编译时间。如果再定义一个字符指针:char*pname=name;则name[i]、*和*具有相同的值,都是数组第i+1个元素的值。分析以下程序的执行结果。......
2023-11-07
如同一个变量一样,对象从被创建到被释放为止的时间称为对象的生存期。一个对象的生存期如图2.8所示。从上看到,分配对象的内存空间和调用构造函数进行数据成员初始化是两个不同的阶段。构造函数帮助对象自动进行初始化,并且初始化的同时可以执行其他操作。......
2023-11-07
程序设计是指设计、编写和调试程序的方法与过程。由于程序是软件的本体,因此软件的质量主要通过程序的质量体现,因此,研究一种切实可行的程序设计方法至关重要。继承是面向对象程序设计方法的一个重要标志,利用继承机制可以大大提高程序的可重用性和可扩充性。......
2023-11-07
派生类的对象不仅存放了在派生类中定义的非静态数据成员,而且也存放了从基类中继承下来的所有非静态数据成员,因而在派生类中存放的这些从基类继承下来的数据存储又称派生类对象的子对象。图6.8对象a和b的存储空间分配与非静态数据成员存储方式不同,基类与派生类的静态数据成员与成员函数是共享的。当派生类B对象使用从基类A继承下来的setvaluea和dispa成员函数时,编译系统会自动将这一调用映射到基类存放的代码。......
2023-11-07
相关推荐