MFC: std :: string vs CString? - PullRequest
       49

MFC: std :: string vs CString?

20 голосов
/ 25 мая 2011

Использование C ++ с MFC.Исходя из C # фона, я обычно просто использую строку для всех, ну, для строк.Я использую их для членов класса, параметров метода и возвращаемых значений метода.

Теперь в C ++ у меня есть std :: string, CString, char *, LPCTSTR и другие.Когда я проектирую свои члены данных, параметры метода и возвращаемые значения метода, какой тип (типы) я должен использовать?Простота использования важна, и CString, кажется, предлагает это, но мой инстинкт направлен на портативные стандарты, хотя переносимость довольно низкая в моем списке приоритетов (сейчас).Кроме того, мне не нравится семантика c создания строковых буферов и передачи их в методы и функции.

Я думаю, что с точки зрения простоты кодирования CStrings, вероятно, имеют преимущество.Но в целом, что такое «высокое качество кода», способ сделать это?

РЕДАКТИРОВАТЬ:

Меня особенно беспокоит точки интерфейса в моем коде (т.е. параметры метода и возвращаемые значения).Например:

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

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

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

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

Ответы [ 4 ]

19 голосов
/ 25 мая 2011

Я обычно предпочитаю адаптировать свой стиль кодирования к среде, в которой я работаю, чтобы соответствовать ей. Поэтому, когда я работаю с MFC (чего у меня давно нет), я предпочитаю использовать CStringLPCTSTR в качестве аргументов функций в методах открытого интерфейса). При работе с Qt я предпочитаю QString и контейнеры Qt, а не контейнеры STL, и для всего, что не имеет прямого отношения к такой среде, я использую std::string, так как это стандартный C ++ способ обработки строк.

Это не имеет такого большого значения, поскольку все они предлагают более или менее одинаковую функциональность (и легко конвертируются друг в друга), и когда код написан для определенной среды, это все равно зависит от него, поэтому переносимость не такая большая проблема.

Только не беспокойтесь о простых массивах символов! И, между прочим, попробуйте передать объекты по константной ссылке (const std::string &caption), а не по значению, так как в C ++ переменные не являются автоматически ссылками, и копирование строки может быть довольно дорогим.

7 голосов
/ 25 мая 2011

MFC был написан с ожиданием того, что вы будете использовать CString. Это особенно очевидно, когда функция использует параметр для возврата строки. Например, сравните эти два вызова с GetWindowText:

CString s1;
wnd.GetWindowText(s1);

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

Преобразование между ними не так уж и плохо, так что вы можете пойти на компромисс, используя std :: wstring для большинства вещей и временную CString, когда это необходимо.

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

Редактировать: Может быть способ автоматизировать временную строку CString. Честное предупреждение, это полный взлом. Я не пробовал это, так что никаких гарантий - вы, вероятно, получите предупреждения о привязке временного к неконстантной ссылке, но вы можете отключить их.

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));
3 голосов
/ 25 мая 2011

Не используйте CString.Он использует реализацию COW, которая очень уязвима для таких вещей, как многопоточность.Не используйте char* или LPCTSTR (это просто const char* или const wchar_t* под другим именем), так как они не управляют своей собственной памятью.Используйте std::string для 8-битных кодовых точек или std::wstring для 16-битных кодовых точек в Windows (32-битная для Unix).

3 голосов
/ 25 мая 2011

Если вы заботитесь о переносимости и используете C ++, используйте std::string. Нет смысла переходить на низкий уровень с массивами char, если вам это не нужно. Если вас не волнует переносимость, а предоставляемые платформой строки предоставляют больше функций, которые вам нужны, во что бы то ни стало, используйте их. На самом деле они могут быть более оптимизированы для платформы.

...