MFC: std:: string vs CString?

utiliser C++ avec MFC. Venant d'un c # background j'utilise typiquement string pour tous, bien, strings. Je les utilise pour les membres de classe, les paramètres de méthode, et les valeurs de retour de méthode.

maintenant en C++ j'ai std::string, CString, char *, LPCTSTR, et plus encore. Comme je conçois mes membres de données, les paramètres de la méthode, et les valeurs de retour des méthodes type(s) dois-je utiliser? La facilité d'utilisation est importante et CString semble offrir que, mais mon instinct est vers les normes portables bien que la portabilité est assez bas sur ma liste de priorités (maintenant). En outre, je n'aime pas la sémantique de créer des tampons de chaîne et de les passer dans les méthodes et les fonctions.

je pense que d'un point de vue de la facilité immédiate de codage CStrings CStrings ont probablement le bord. Mais, dans l'ensemble, Quelle est la façon "de haute qualité de code" de faire cela?

EDIT:

je suis particulièrement préoccupé par les points d'interface dans mon code (i.e. les paramètres de méthode et les valeurs de retour). E. g.:

Shape::SetCaption(const char *caption) {...}

Shape::SetCaption(CString caption) {...}

Shape::SetCaption(std::string caption) {...}

Shape::SetCaption(std::wstring caption) {...}
20
demandé sur User 2011-05-25 01:42:32

4 réponses

je préfère généralement adapter mon style de codage au cadre dans lequel je travaille pour être cohérent avec celui-ci. Donc quand je travaille avec MFC (ce que je n'ai pas fait depuis longtemps), je préfère l'utilisation de CString (et LPCTSTR comme arguments de fonction dans les méthodes d'interface publique). Quand je travaille avec Qt, je préfère QString et les conteneurs de Qt sur les conteneurs STL et pour tout ce qui n'est pas directement lié à un tel cadre j'utilise std::string car c'est la façon standard C++ de gérer les chaînes.

Il n'a pas faire une telle différence, car ils offrent tous des fonctionnalités plus ou moins égales (et sont facilement transposables les uns dans les autres) et quand le code est écrit pour un certain cadre, il dépend de lui de toute façon, de sorte que la portabilité n'est pas un problème si énorme.

ne vous embêtez pas avec des tableaux de char simples! Et au fait, essayez de passer des objets par référence à const (const std::string &caption) et non par la valeur, comme dans C++ Les variables ne sont pas automatiquement des références et copier une chaîne de caractères peut devenir très coûteux.

18
répondu Christian Rau 2011-05-25 00:22:32

MFC a été écrit avec l'espoir que vous utilisiez CString. C'est particulièrement évident lorsqu'une fonction utilise un paramètre pour renvoyer une chaîne de caractères. Par exemple, comparez ces deux appels à GetWindowText:

CString s1;
wnd.GetWindowText(s1);

std::wstring s2(SOME_MAX, 0);
int len = wnd.GetWindowText(&s2[0], s2.size());
s2.resize(len);

convertir entre les deux n'est pas mauvais cependant, donc vous pourriez compromettre en utilisant std::wstring pour la plupart des choses et un CString temporaire lorsque nécessaire.

CString s3 = s2.c_str();
std::wstring s4 = s1;

Edit: il peut y avoir un moyen d'automatiser le CString temporaire. Avertissement juste, c'est un hack. Je n'ai pas essayé cela, donc aucune garantie - vous obtiendrez probablement des avertissements au sujet de lier un temporaire à une référence non-const, mais vous pouvez éteindre ceux-ci.

class PopString : public CString
{
public:
    PopString(std::wstring & final) : m_final(final)
    {
    }

    ~PopString()
    {
        m_final = (PCTSTR) *this;
    }
private:
    PopString(const PopString &) {}  // private copy constructor to prevent copying
    PopString & operator=(const PopString &) {}  // private copy operator

    std::wstring & m_final;
};

std::wstring s5;
wnd.GetWindowText(PopString(s5));
7
répondu Mark Ransom 2011-05-24 22:38:19

si vous vous souciez de la portabilité et que vous utilisez C++, utilisez std::string. Pas la peine d'aller au bas de l'échelle avec char tableaux si vous n'en avez pas besoin. Si vous ne vous souciez pas de la portabilité et les chaînes fournies par la plate-forme fournissent plus de fonctionnalités dont vous avez besoin, par tous les moyens, utilisez-les. Ils pourraient en fait être plus optimisés pour la plate-forme.

3
répondu rid 2011-05-24 21:46:09

N'utilisez pas CString. Il utilise une implémentation de vache qui est très vulnérable à des choses comme le filetage. Ne pas utiliser char* ou LPCTSTR (const char* ou const wchar_t* sous un autre nom), car ils ne gèrent pas leur propre mémoire. Utiliser un std::string pour les codépoints de 8 bits ou std::wstring pour les codépoints 16 bits sur Windows (32 bits pour Unix).

3
répondu Puppy 2011-05-25 09:00:41