Подтвердить что ты не робот

MFC: std::string против CString?

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

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

Я думаю, что с непосредственной простоты кодирования перспективы CStrings, вероятно, имеют преимущество. Но, в целом, каков способ "высокого качества кода"?

EDIT:

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

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

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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 4

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