9.9.9 通用类(2)
该示例产生下面的输出:
- The array of boxes have the following volumes:
- CBox usable volume is 24
- CBox usable volume is 20.4
- CBox usable volume is 120
- CBox usable volume is 102
-
- Now pushing the boxes on the stack...
- Popping the boxes off the stack presents them in reverse order:
- CBox usable volume is 102
- CBox usable volume is 120
- CBox usable volume is 20.4
- CBox 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对象句柄的堆栈是在下面这条语句中定义的:
- Stack<Box^>^ stack = gcnew Stack<Box^>; // Create the stack
类型形参是Box^,因此该堆栈可以存储Box对象的句柄或GlassBox对象的句柄。将对象压入堆栈以及从堆栈弹出的代码与Ex9_14示例中完全相同,因此输出也相同。这里的区别在于,如果某个类型不是以Box为直接或间接基类,我们就不能将该类型的对象压入堆栈。因此,通用类型能够保证所有对象都是Box对象。
现在,存储整数需要一个新的Stack<>对象:
- Stack<int>^ numbers = gcnew Stack<int>; // Create the stack
原来的版本使用同一个非通用Stack对象来存储Box对象引用和整数,从而证实了在该堆栈的操作中完全缺少类型安全性。在这里,我们将通用类的类型实参指定为数值类型int,因此只有该类型的对象才能被Push()函数接受。
将对象从堆栈弹出的两个循环证实,在函数中返回T()确实为int类型返回了0,为Box^句柄类型返回了nullptr。
1. 通用接口类
我们可以定义通用接口,其方法与定义通用引用类的相同,通用引用类可以根据通用接口进行定义。为了说明工作过程,我们可以定义一个能够由通用类Stack<>实现的通用接口。下面是某个通用接口的定义:
- // Interface for stack operations
- generic<typename T> public interface class IStack
- {
- void Push(T obj); // Push an item on to the stack
- T Pop();
- };
该接口有两个标识堆栈的入栈和出栈操作的函数。
实现IStack<>通用接口的通用Stack<>类的定义如下:
- generic<typename T> ref class Stack : IStack<T>
- {
- private:
- // Defines items to store in the stack
- ref struct Item
- {
- T Obj; // Handle for the object in this item
- Item^ Next; // Handle for next item in the stack or nullptr
-
- // Constructor
- Item(T obj, Item^ next): Obj(obj), Next(next){}
- };
-
- Item^ Top; // Handle for item that is at the top
-
- public:
- // Push an object on to the stack
- virtual void Push(T obj)
- {
- Top = gcnew Item(obj, Top); // Create new item and make it the top
- }
-
- // Pop an object off the stack
- virtual T Pop()
- {
- if(Top == nullptr) / / If the stack is empty
- return T(); // return null equivalent
-
- T obj = Top->Obj; // Get object from item
- TopTop = Top->Next; // Make next item the top
- return obj;
- }
- };
对前面的通用Stack<>类定义所作的修改以阴影显示。在这个通用类定义的第一行,类型形参T被用作接口IStack的类型实参,因此用于Stack<>类实例的类型实参将同样应用于IStack接口。该类的Push()和Pop()函数现在必须被指定为virtual,因为它们在IStack接口中是虚函数。我们可以给上一个示例添加包含IStack接口的头文件,然后修改该示例的通用Stack<>类定义,并重新编译程序,以了解使用通用接口之后该程序的工作情况。