const int MAXSTACK = 1000;
class Stack
{
protected:
int* const m_pItems;
int m_nTop;
public:
enum { FullStack = MAXSTACK, EmptyStack = -1 };
Stack()
: m_pItems(new int[MAXSTACK])
{
m_nTop = EmptyStack;
}
~Stack()
{
delete [] m_pItems;
}
void Push(int nValue)
{
if (!IsFull())
m_pItems[++m_nTop] = nValue;
}
int Pop(void)
{
int nValue = m_pItems[m_nTop];
if (!IsEmpty())
m_nTop--;
return nValue;
}
bool IsEmpty() { return m_nTop == EmptyStack; }
bool IsFull() { return m_nTop == FullStack - 1; }
};
Collection Method/Property |
Required? | Description |
Count | Yes | This property returns the number of items in the collection. Its DISPID can be any number. |
_NewEnum | Yes | This property returns a generic interface pointer to an IEnumVARIANT enumerator. Its DISPID is unique and must be set to DISPID_NEWENUM (–4), meaning that the name of this method need not be localized. It should be declared in IDL using the restricted keyword so that it is not visible to macro programming languages like VBScript. |
Item | Yes | This method returns the indicated item in the collection or NULL if the requested item does not exist. It must be the default member of the class, so its DISPID must be set to DISPID_VALUE (0). |
Add | No | This method adds the indicated item to the collection. If an object is created as a result of the addition, a pointer to that object should be returned. |
Remove | No | This method removes an item from the collection. It supports the same indexing as the Item method. The Remove method should not attempt to force deletion of the object; rather, it should release its reference to the object and remove it from the collection. |
interface IAnimals : IDispatch
{
[propget, restricted, id(DISPID_NEWENUM),
helpstring("property _NewEnum")]
HRESULT _NewEnum([out, retval] IUnknown** pVal);
[id(DISPID_VALUE), helpstring("method Item")]
HRESULT Item([in] VARIANT index, [out, retval] IDispatch** ppItem);
[propget, id(1), helpstring("property Count")]
HRESULT Count([out, retval] long *pVal);
// Optional Add and Remove methods. These signatures are
// implementation-dependent.
[id(2), helpstring("method Add")]
HRESULT Add([in] BSTR name, [out, retval] IDispatch** ppItem);
[id(3), helpstring("method Remove")]
HRESULT Remove([in] VARIANT index);
};
IEnumXxxx Methods | Description |
Next | Retrieves a specified number of items in the enumeration sequence. The data type of the items returned depends on the collection being enumerated. |
Skip | Skips over a specified number of items in the enumeration sequence. |
Reset | Resets the enumeration sequence to the beginning. |
Clone | Creates another enumerator that contains the same enumeration state as the current one. |
STDMETHODIMP CAnimals::Item(VARIANT index, IDispatch** ppItem)
{
switch(index.vt)
{
// If the VARIANT is a BSTR, let's look up the Animal
// by name!
case VT_BSTR:
{
bstr_t bstrName(index.bstrVal);
std::vector<IAnimal*>::iterator item = m_itemList.begin();
for (; item != m_itemList.end(); item++)
{
CComBSTR bstrItem;
(*item)->get_Name(&bstrItem);
if (bstrName == bstr_t(bstrItem))
{
return (*item)->QueryInterface(IID_IDispatch,
(void**)ppItem);
}
}
return E_FAIL;
}
// If the VARIANT is a long integer, let's look up the Animal
// by offset!
case VT_I4:
{
if (index.lVal < 0 || index.lVal >= m_itemList.size())
return E_FAIL;
return m_itemList[index.lVal]->QueryInterface(
IID_IDispatch, (void**)ppItem);
}
// If the VARIANT is neither of those, we'll punt!!
default:
return E_FAIL;
}
}
Interface | Methods | Description |
ICollectXxxx | Item | Returns a pointer to the desired IXxxx interface |
Count | Returns the number of objects in the collection | |
EnumCollection | Returns a pointer to IEnumXxxx interface | |
ICollectOwnerXxxx | Add | Adds an item to the collection |
Remove | Removes an item from the collection | |
IEnumXxxx | Next | Retrieves the specified number of items |
Skip | Skips over the specified number of items | |
Reset | Resets the enumeration sequence to the beginning | |
Clone | Creates another enumerator with same state |