Classe de sequência personalizada (C ++)

Estou tentando escrever minha própria classe C ++ String para fins educacionais e de necessidade.
A primeira coisa é que eu não sei muito sobre operadores e é por isso que quero aprendê-los. Comecei a escrever minha classe, mas quando a executo, ela bloqueia o programa, mas não causa nenhum travamento.
Dê uma olhada no código a seguir antes de ler mais:

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);
};

Antes de tudo, não tenho tanta certeza de ter declarado tudo certo. Eu tentei pesquisar no google, mas todos os tutoriais sobre sobrecarga explicam a idéia básica, que é muito simples, mas falta explicar como e quando cada coisa é chamada. Por exemplo, no meu operador =, o programa chama CString (CString & str); mas não tenho idéia do porquê.
Também anexei o arquivo cpp abaixo:

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 testar, usei um código tão simples quanto este
CString a = CString ("Olá") + CString ("Mundo");
printf (a);
Eu tentei depurar, mas em um momento eu me perco. Primeiro, ele chama o construtor 2 vezes para "olá" e "mundo". Então fica no operador +, o que é bom. Em seguida, chama o construtor para a sequência vazia. Depois disso, ele entra no "CString (CString & str)" e agora estou perdido. Por que isso está acontecendo? Depois disso, notei que minha string contendo "Hello World" está no destruidor (algumas vezes seguidas). Mais uma vez estou muito intrigado. Depois de converter novamente de char * para Cstring e para frente e para trás, ele para. Ele nunca entra no operador =, mas também não vai mais longe. printf (a) nunca é alcançado.
Eu uso o VisualStudio 2010 para isso, mas é basicamente apenas código c ++ padrão e, portanto, acho que não deve fazer muita diferença

questionAnswers(1)

yourAnswerToTheQuestion