Использование умных указателей

331
26 февраля 2017, 08:57

У меня в коде часто повторяется фрагмент:

TCHAR text[10] = {};
Convert(window, id1, text);

Я его хочу вынести в отдельную функцию, которая будет возвращать указатель на text.

TCHAR* Foo(HWND window, int id)
{
    TCHAR *text = new TCHAR[10];
    Convert(window, id, text);
    return text;
}

Когда надо будет освободить память, мне не известно. Поэтому, я воспользовалась умными указателями:

std::shared_ptr<TCHAR> Foo(HWND window, int id)
{
    std::shared_ptr<TCHAR> text;
    Convert(window, id, text); //no suitable conversion function from  
                               //"std::shared_ptr<TCHAR>" to "TCHAR *"  
    return text;
}
void Convert(HWND window, int ID, TCHAR* text, int size=10)
{
    HWND handle = GetDlgItem(window, ID);
    GetWindowText(handle, text, size);
}

Как выделить память на 10 элементов и решить проблему с преобразованием?

Answer 1

Чтобы std::shared_ptr правильно работал с массивами, для него нужно задать пользовательский deleter. Или, если Ваш компилятор поддерживает c++17, то можно параметризовать std::shared_ptr типом массива, например, TCHAR[] (спасибо за уточнение GreenDragon). Иначе в коде появляется UB, т.к. освобождение объекта будет происходить через delete, а не delete[] как это требуется после выделения памяти через new[].

В данном случае общее владение в принципе не требуется, поэтому можно воспользоваться специализацией std::unique_ptr для массивов. Однако зная специфику Вашей функции Convert можно было бы посоветовать вовсе отказаться от ручного управления памятью и умных указателей в частности, и использовать std::basic_string<TCHAR>, например.

Т.е. я бы предложил переделать Convert как-то так:

std::basic_string<TCHAR> Convert(HWND window, int ID)
{
    HWND handle = GetDlgItem(window, ID);
    std::basic_string<TCHAR> ret(GetWindowTextLength(handle) + 1, _T(' '));
    GetWindowText(handle, ret.data(), ret.size());
    return ret;
}

Но может быть тут надо учесть ещё какие-то особенности WinAPI.

READ ALSO
MessageBox попадает в бесконечный цикл WinApi

MessageBox попадает в бесконечный цикл WinApi

Пишу простейший калькулятор с помощью WinApi, когда происходит деление на 0 нужно вывести MessageBox с ошибкойНо в калькуляторе есть функция auto-reresh,...

468
Найти отличное от других число

Найти отличное от других число

Есть последовательность различных int чиселНеобходимо эффективно найти любое int число, отличающееся от данных

429
C++ 17, std::experimental::any где?

C++ 17, std::experimental::any где?

Работаю в MSVC, набираю #include <experimental/ >, в выпадающем списке нет anyКак мне подключить этот хедер?

419
Достаточный для хранения 2x числа тип

Достаточный для хранения 2x числа тип

У меня есть числоКак получить тип, который может хранить это число, умноженное на 2, если число имеет не "максимальный" тип? Например, число...

334