Clase de cadena personalizada (C ++)

Estoy tratando de escribir mi propia clase de C ++ String con fines educativos y de necesidad.
Lo primero es que no sé mucho sobre operadores y es por eso que quiero aprenderlos. Empecé a escribir mi clase, pero cuando la ejecuto bloquea el programa pero no se bloquea.
Eche un vistazo al siguiente código antes de seguir leyendo:

class CString
{
private:
  char* cstr;
public:
  CString();
  CString(char* str);
  CString(CString& str);
  ~CString();

  operator char*();
  operator const char*();
  CString operator+(const CString& q)const;
     CString operator=(const CString& q);
};

En primer lugar, no estoy tan seguro de haber declarado todo bien. Intenté googlear al respecto, pero todos los tutoriales sobre sobrecarga explican la idea básica, que es muy simple pero no explica cómo y cuándo se llama cada cosa. Por ejemplo, en mi operador = el programa llama a CString (CString & str); pero no tengo idea de por qué.
También he adjuntado el archivo cpp a continuación:

CString::CString()
{
 cstr=0;
}
CString::CString(char *str)
{
 cstr=new char[strlen(str)];
 strcpy(cstr,str);
}
CString::CString(CString& q)
{
 if(this==&q)
  return;
 cstr = new char[strlen(q.cstr)+1];
 strcpy(cstr,q.cstr);
}
CString::~CString()
{
 if(cstr)
  delete[] cstr;
}
CString::operator char*()
{
 return cstr;
}
CString::operator const char* ()
{
 return cstr;
}
CString CString::operator +(const CString &q) const
{
 CString s;
 s.cstr = new char[strlen(cstr)+strlen(q.cstr)+1];
 strcpy(s.cstr,cstr);
 strcat(s.cstr,q.cstr);
 return s;
}
CString CString::operator =(const CString &q)
{
 if(this!=&q)
 {
  if(cstr)
   delete[] cstr;
  cstr = new char[strlen(q.cstr)+1];
  strcpy(cstr,q.cstr);
 }
 return *this;
}

Para probar usé un código tan simple como este
CString a = CString ("Hola") + CString ("Mundo");
printf (a);
Intenté depurarlo pero en un momento me pierdo. Primero llama al constructor 2 veces para "hola" y para "mundo". Luego se pone en el operador + que está bien. Luego llama al constructor para la cadena vacía. Después de eso, entra en "CString (CString & str)" y ahora estoy perdido. ¿Por qué está pasando esto? Después de esto, noté que mi cadena que contenía "Hello World" está en el destructor (varias veces seguidas). De nuevo estoy muy perplejo. Después de convertir nuevamente de char * a Cstring y viceversa, se detiene. Nunca ingresa al operador = pero tampoco va más allá. printf (a) nunca se alcanza.
Utilizo VisualStudio 2010 para esto, pero básicamente es solo un código estándar de C ++ y, por lo tanto, no creo que deba hacer tanta diferencia

Respuestas a la pregunta(1)

Su respuesta a la pregunta