length c++ array
MFC: std:: string vs CString? (4)
Usando C ++ con MFC. Viniendo de un fondo de C #, normalmente uso cadenas para todas las cadenas. Los uso para miembros de clase, parámetros de método y valores de retorno de método.
Ahora en C ++ tengo std :: string, CString, char *, LPCTSTR, y más. Cuando diseño mis miembros de datos, parámetros de método y valores de retorno de método, ¿qué tipo (s) debo usar? La facilidad de uso es importante y CString parece ofrecer eso, pero mi instinto es hacia los estándares portátiles aunque la portabilidad es bastante baja en mi lista de prioridades (ahora). Además, no me gusta la semántica c de crear búferes de cadena y pasarlos a métodos y funciones.
Creo que desde una perspectiva inmediata de codificación, CStrings probablemente tenga la ventaja. Pero, en general, ¿cuál es la forma de "alta calidad de código" para hacer esto?
EDITAR:
Estoy especialmente preocupado por los puntos de interfaz en mi código (es decir, parámetros de método y valores de retorno). P.ej:
Shape::SetCaption(const char *caption) {...}
Shape::SetCaption(CString caption) {...}
Shape::SetCaption(std::string caption) {...}
Shape::SetCaption(std::wstring caption) {...}
MFC fue escrito con la expectativa de que usarías CString. Esto es especialmente evidente cuando una función usa un parámetro para devolver una cadena. Por ejemplo, compare estas dos llamadas con GetWindowText:
CString s1;
wnd.GetWindowText(s1);
std::wstring s2(SOME_MAX, 0);
int len = wnd.GetWindowText(&s2[0], s2.size());
s2.resize(len);
Sin embargo, la conversión entre los dos no es mala, por lo que puedes comprometerte utilizando std :: wstring para la mayoría de las cosas y un CString temporal cuando sea necesario.
CString s3 = s2.c_str();
std::wstring s4 = s1;
Editar: Puede haber una manera de automatizar el CString temporal. Advertencia justa, este es un truco completo. No he intentado esto, así que no hay garantías: es probable que reciba advertencias sobre la vinculación de una referencia temporal a una no constante, pero puede desactivarlas.
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));
No utilice CString. Utiliza una implementación de COW que es muy vulnerable a cosas como subprocesos. No utilice char*
o LPCTSTR
(que es simplemente const char*
o const wchar_t*
con un nombre diferente), ya que no administran su propia memoria. Use una std::string
para puntos de código de 8 bits o std::wstring
para puntos de código de 16 bits en Windows (32 bits para Unix).
Normalmente prefiero adaptar mi estilo de codificación al marco en el que estoy trabajando para ser coherente con él. Entonces, cuando trabajo con MFC (que no tengo desde hace mucho tiempo), prefiero el uso de CString
(y LPCTSTR
como argumentos de función en los métodos de interfaz pública). Cuando trabajo con Qt, prefiero los contenedores QString
y Qt sobre los contenedores STL y para todo lo que no esté directamente relacionado con dicho marco, utilizo std::string
ya que es la forma estándar de C ++ de manejar cadenas.
No hace una gran diferencia, ya que todos ofrecen una funcionalidad más o menos igual (y son fácilmente convertibles entre sí) y cuando el código se escribe para un determinado marco, depende de ello de todos modos, por lo que la portabilidad no es tal. gran preocupación
¡Simplemente no te molestes con las matrices de char! Y, por cierto, intente pasar los objetos por referencia constante ( const std::string &caption
) y no por valor, ya que en C ++ las variables no son referencias automáticamente y copiar una cadena puede resultar bastante costoso.
Si te importa la portabilidad y estás usando C ++ usa std::string
. No tiene sentido ir a bajo nivel con matrices de caracteres si no es necesario. Si no le importa la portabilidad y las cadenas proporcionadas por la plataforma proporcionan más de las funciones que necesita, por supuesto, úselas. De hecho, podrían estar más optimizados para la plataforma.