9.9.2 C++(www.cppentry.com)/CLI类的继承(3)
该示例的输出如下:
- The array of boxes have the following volumes:
- Box usable volume is 24
- Box usable volume is 20.4
- Box usable volume is 120
- Box usable volume is 102
-
- Now pushing the boxes on the stack...
- Popping the boxes off the stack presents them in reverse order:
- Box usable volume is 102
- Box usable volume is 120
- Box usable volume is 20.4
- Box usable volume is 24
-
- Now pushing integers on to the stack:
- 2 4 6 8 10 12
- Popping integers off the stack produces:
- 12 10 8 6 4 2
示例说明
我们首先创建了一个Box对象的句柄数组:
- array<Box^>^ boxes = { gcnew Box(2.0, 3.0, 4.0),
- gcnew GlassBox(2.0, 3.0, 4.0),
- gcnew Box(4.0, 5.0, 6.0),
- gcnew GlassBox(4.0, 5.0, 6.0)
- };
因为Box和GlassBox都是引用类,所以我们使用gcnew在CLR堆上创建对象。这些对象的地址将初始化boxes数组的元素。
然后创建了Stack对象,并将先前创建的字符串压入堆栈:
- Stack^ stack = gcnew Stack; // Create the stack
- for each(Box^ box in boxes)
- stack->Push(box);
Push()函数的形参是Object^类型,因此该函数可接受任何类类型的实参。for each循环将boxes数组中各个元素压入堆栈。
将这些元素弹出堆栈的操作发生在while循环中:
- Object^ item;
- while((item = stack->Pop()) != nullptr)
- safe_cast<Container^>(item)->ShowVolume();
循环条件将stack对象的Pop()函数返回的值存入item,并将其与nullptr进行比较。只要没有被设置成nullptr,就执行while循环体包含的那条语句。在该循环内,我们将item中存储的句柄强制转换为Container^类型。item变量属于Object^类型,因为Object类没有定义ShowVolume()函数,所以我们不能使用该类型的句柄调用ShowVolume()函数。为了动态地调用某个函数,我们必须使用将该函数声明为虚成员的基类类型的句柄。将Object^句柄强制转换为Container^类型之后,我们就能多态地调用ShowVolume()函数,因此该函数最终将根据句柄item引用的那个类对象的类型进行选择。在本例中,我们将item强制转换为Box^类型也可以达到相同的结果。这里使用safe_cast的原因在于强制转换是在类层次结构中向上进行的,这种情况下最好使用经过检查的转换操作。safe_cast运算符检查强制转换是否有效,如果转换失败,该运算符将抛出一个System::InvalidCastException类型的异常。我们也可以使用dynamic_cast,但在CLR程序中最好使用safe_cast。