在C++编程时,我们经常遇到一些情况,需要选择模式。比如,利用fstream打开文件时,有选择打开模式。通常选择的是一组数据或运算后的组合,如选择打开文件可进行读写操作,则会选择fstream::in | fstream::out模式。这些是如何实现的?我们这里来讨论一下。以MFC中的CFile类为例,着重讨论模式标志常量的定义和在函数中的使用。
首先,打开afx.h,查找到CFile类声明中,有如下一段,用于定义模式标志值。可以看到,是使用了enum来定义的一个枚举类型,里边包含了所需的常量标志。
public: // Flag values enum OpenFlags { modeRead = (int) 0x00000, modeWrite = (int) 0x00001, modeReadWrite = (int) 0x00002, shareCompat = (int) 0x00000, shareExclusive = (int) 0x00010, shareDenyWrite = (int) 0x00020, shareDenyRead = (int) 0x00030, shareDenyNone = (int) 0x00040, modeNoInherit = (int) 0x00080, modeCreate = (int) 0x01000, modeNoTruncate = (int) 0x02000, typeText = (int) 0x04000, // typeText and typeBinary are typeBinary = (int) 0x08000, // used in derived classes only osNoBuffer = (int) 0x10000, osWriteThrough = (int) 0x20000, osRandomAccess = (int) 0x40000, osSequentialScan = (int) 0x80000, };
再看构造函数和打开函数:
CFile(LPCTSTR lpszFileName, UINT nOpenFlags);
virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL);
通过UINT的数据组合传入选择的模式标志值。
再来看函数的定义(filecore.cpp),在Open函数中,有如下一段。可以看出,在函数定义中,通过与操作和switch-case结构结合,查找出所选择的模式。
switch (nOpenFlags & 3) { case modeRead: dwAccess = GENERIC_READ; break; case modeWrite: dwAccess = GENERIC_WRITE; break; case modeReadWrite: dwAccess = GENERIC_READ | GENERIC_WRITE; break; default: ASSERT(FALSE); // invalid share mode }因此,总结下来,如果希望实现上述选择模式标志的功能, 需要做三步:一是在类中采用enum定义自己模式标志常量值;二是在函数入口参数中传入模式标志值,可通过或运算进行组合,通常变量可以是int或unsigned int 或者直接是枚举类型;三是在函数内部使用与操作找出选择的模式,进行相应的处理。