Mental Jetsam

By Peter Finch

Archive for the ‘C++/MFC’ Category

C++ STL vector of pointers

Posted by pcfinch on October 11, 2010

Storing pointers in a C++ STL vector (e.g. vector<CBase *>) can be problematic, as you always have to remember to manually delete the pointers from the vector before deleting the vector, or before the vector goes out of scope. A simple way to get around the problem, is to subclass the vector template with another template and provide a destructor that deletes the contents of the array.

template<class _T> class prt_vector : public vector<_T*> {
public :
  virtual ~prt_vector() {
    for (unsigned int i=0; i<size(); i++) 
      delete (*this)[i] ;
  } ;
} ;

prt_vector<CBase> list ;
list.push_back(new CBase("Peter") ) ;
list.push_back(new CCake("Annette", "Fruit") ) ;

for (unsigned int i=0; i<list.size(); i++) {
  list[i]->print(cout) ; 
}

Storing pointers to the objects in the vector means you also get the added advantage of being able to store subclasses of the base class in the vector as well.

Advertisements

Posted in C++/MFC | Leave a Comment »

Browser slow to connect to localhost on Vista

Posted by pcfinch on July 11, 2008

I’m developing a little HTTP server in C++ on vista (don’t ask why). Anyway, I found that my browser was REALLY slow when trying to connect to the localhost server “http://localhost:8282/&#8221; but not the local IP address “http://127.0.0.1:8282/&#8221;. When I say slow, I mean about 1 second per connection. A bit of hunting around and I found the following lines in the \windows\system32\drivers\etc\hosts file.

127.0.0.1       localhost
::1             localhost

I didn’t recognize the last line or know what it does… so I commented it out (I live life on the edge some time!!). Anyway, things sped up! e.g.

127.0.0.1       localhost
# ::1             localhost

You’ll have to edit the hosts file as the administrator as it’s protected, but this simple little fixed work for me. If your having a similar problem, I hope this helps you too.

Posted in C++/MFC, Vista | 5 Comments »

Replace a string with a character in C

Posted by pcfinch on June 26, 2008

This code is a simple string search and replace function in C/C++. It searches a NULL terminated string and replaces all the matching strings with a single character. For example, find all the occurrences of “&” is a string and replace them with “&”. The code is fast, as it only performs one single pass of the string. The code modifies the existing string, so care should be taken when using it, however, as the matched string can only ever be replaced with a single character the resulting string will never be larger that the original string, so it’s a pretty safe function.

void str_replace_c(char*pszString, char* pszMatch, char cTo)
{
  char* pStart = NULL ;
  char* pInMatch = pszMatch ;
  char* pInString = pszString ;
  char* pOutString = pszString ;
  char c ;

  if((pszString == NULL) ||
     (pszMatch == NULL) ||
     (*pszString == ''))
    return ;

  do {
    c = *(pInString++) ;
    if(pStart == NULL) {
      if(c == *pszMatch) {
        pStart = pOutString ;
        pInMatch = pszMatch + 1 ;
      }
    } else {
      if(*pInMatch == '') {
        pOutString = pStart ;
        *(pOutString++) = cTo ;
        pStart = NULL ;
      } else {
        if(*pInMatch == c)
          pInMatch++ ;
        else
          pStart = NULL ;
      }
    }
    *(pOutString++) = c ;
  } while(c != '') ;
}

int main()
{
  char in[] = "& amp; This is & amp; a test & amp;" ;
  str_replace_c(in, "& amp;", '&') ;
  printf("out=\"%s\"\n", in) ;
}

Posted in C++/MFC | Leave a Comment »

Simple C++ CWinThread Example

Posted by pcfinch on September 21, 2007

Creating a background thread in MFC is pretty simple but there is a little trick. Don’t forget to create a InitInstance() virtual function as well as the Run() function. The MFC CWinThread initialization process calls InitInstance() when it first creates the thread and expects a TRUE return value. The default function returns FALSE so the thread will not start. Here is some simple code to start a background thread using MFC.


class CServiceAdapter : public CWinThread
{
public:
    CServiceAdapter();
    virtual ~CServiceAdapter();
    virtual BOOL InitInstance() ;
    virtual int Run() ;
    CString sName ;
} ;

BOOL CServiceAdapter::InitInstance()
{
    return TRUE;
}

int CServiceAdapter::Run()
{
	TRACE(_T("CServiceAdapter: Run() calledn")) ;
	return (0) ;
}

You can simply call the CreatThread() function on the object (inherited from CWinThread) but that starts the thread immediately and does not give you an opportunity to perform any initialization on the contents of the object and can sometime cause a race condition. A nice way to start the thread [I think] is to start it suspended, do some initialization and then resume it. I have set the m_bAutoDelete to false so that when the thread is finished I can still access the contents of the class to get the results, but that’s optional. Setting it to true (the default) means that when the thread terminates the object will automatically be deleted.


CServiceAdapter* adapter = new CServiceAdapter() ;
adapter->CreateThread(CREATE_SUSPENDED) ;
adapter->m_bAutoDelete = false ; // Let me delete it.
adapter->sName = _T("Test") ; // Initialize something
adapter->ResumeThread() ;

To wait for the thread to exit use one of the many Wait for Object functions like WaitForSingleObject(). If you set bAutoDelete to false don’t forget to delete the object when you done.


WaitForSingleObject(adapter->m_hThread, INFINITE) ;
delete(adapter) ;

Posted in C++/MFC | 4 Comments »