Today a person asked, how to use existing sort function of Visual C Runtime library with MFC CArray object. It’s pretty interesting. STL and CRT has implemented some best piece of code for sorting. So you don’t have to burn you brain cell again to implement a sort functionality for your MFC collection classes like CArray and it’s derivatives like CStringArray (should be an object implemented sequential storage. In my understanding CList is not well suited for this).
So how can you do that? See the sample below. Check the comments as well to understand the implementation.
// Typedef of comparison prototypes
typedef int (__cdecl *GENERIC_COMPARE_FXN) ( const void * elem1, const void * elem2 );
typedef int (__cdecl *STRING_COMPARE_FXN )( const CString * elem1, const CString * elem2);
// Class derived from CArray or it's derivatives
class CSortableStringArray : public CStringArray
{
public:
void Sort(STRING_COMPARE_FXN pfnCompare = Compare);
protected:
static int __cdecl Compare(const CString * pstr1, const CString * pstr2);
};
/*
* Implement your own compare function for your class.
* can be either static or global
*/
int CSortableStringArray::Compare(const CString * pstr1, const CString * pstr2)
{
int nRet = 0;
if( pstr1 && pstr2 )
nRet = pstr1->Compare ( *pstr2 ); // Use CompareNoCase for case insensitive comparison
return nRet;
}
/*
* Sort Function
*/
void CSortableStringArray::Sort( STRING_COMPARE_FXN pfnCompare)
{
CString * pcsInternalStr = GetData();
// Call quick sort function
qsort( pcsInternalStr, // pointer to string
GetSize(),sizeof(CString), // number and size of elements
(GENERIC_COMPARE_FXN)pfnCompare // routine for comparison
);
// You can define your own routine which accepts two pointers(should be)
// and typecast it to GENERIC_COMPARE_FXN when passing to qsort
}
OK here’s a peice of code to test your class
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
srand( (unsigned)time( NULL ) ); // Generate seed for rand().
CSortableStringArray arr;
CString str;
for (int i=0; i< 1000;i++)
{
str.Format( _T("%6d"), rand());// Get a random number string.
arr.Add(str);
_tcprintf( _T("%s\n"), (LPCTSTR)str);
}
long ltim=GetTickCount();
arr.Sort();
for (int i=0; i< 1000;i++)
{
_tcprintf( _T("%s\n"), (LPCTSTR)arr[i]);
}
}
return nRetCode;
}
The code is compiled and verfied under Visual C++ 2008. You can implement your own class derived from CArray to implement the sort functionality like this. The only thing you've to do is that, the apt comparison routine must be provided with the type of CArray object being instantiated. This can be either static or global.
MSDN has a KB article on this. Please check
