использовать vector‹wchar› вместо динамически выделяемого массива wchar

На днях меня отчитали (в stackoverflow!) за то, что я не использовал вектор вместо динамически распределяемого массива wchar.

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

Я пришел к выводу, что если я не использую класс векторного шаблона неправильно, использование вектора гораздо менее гибко, чем использование массива, выделенного в куче, и старого доброго memcpy.

#include <shlobj.h>
HRESULT ModifyTheme()
{
using namespace std;

vector <WCHAR>  sOutput;
vector <WCHAR>  sPath;      
vector <WCHAR>  sThemesLocation;
vector <WCHAR>  sThemeName; 

const WCHAR sThemesPath []  = _T("\\Microsoft\\Windows\\Themes");
const WCHAR sFileName []    = _T("\\darkblue.theme");

sOutput.resize(MAX_PATH);
sPath.resize( MAX_PATH );   
sThemesLocation.resize( MAX_PATH );
sThemeName.resize( MAX_PATH );

// Get appdata\local folder
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, &sPath[0] );

// copy consts to vectors   
memcpy( &sThemesLocation[0],    sThemesPath,    sizeof(sThemesPath) );
memcpy( &sThemeName[0],         sFileName,      sizeof(sFileName) );    

// append themes path & filename
sOutput.insert( sOutput.begin(), sPath.begin(), sPath.end() );
sOutput.insert( sOutput.end()-1, sThemesLocation.begin(), sThemesLocation.end() );
sOutput.insert( sOutput.end()-1, sThemeName.begin(), sThemeName.end() );    

wcout << &sThemeName[0] << endl;
wcout << &sThemesLocation[0] << endl;
wcout << &sPath[0] << endl;
wcout << &sOutput[0] << endl;

return S_OK;
}

Я ожидаю, что вектор sOutput будет содержать конкатенацию всех строк. Вместо этого он содержит только первую вставленную строку.

Кроме того, я думаю, что слышал, что, хотя невозможно присвоить значения вектора в списке инициализаторов, это может быть особенностью С++ 0x. Правильно ли это - и есть ли способ (на данный момент) сделать следующее:

vector<wchar> sBleh = { _T("bleh") };

Наконец, для того, чего я хочу достичь с помощью простой процедуры, описанной выше, лучше ли мне использовать динамически распределяемый массив или мне следует продолжать с кажущимся негибким вектором wchar?


person Community    schedule 18.04.2011    source источник
comment
Вы можете попробовать std::wstring.   -  person GManNickG    schedule 18.04.2011
comment
wcout << &sThemeName[0] << endl; печатает содержимое вектора только пока не встретится первый '\0'.   -  person Björn Pollex    schedule 18.04.2011


Ответы (2)


Если вы используете std::vector<WCHAR>, вам, вероятно, следует использовать std::wstring, так как он также является контейнером WCHAR элементов.

Вам могут помочь следующие ссылки:
std::wstring ( typedef of std::basic_string<WCHAR>)
std::basic_string

person Mark Ingram    schedule 18.04.2011

Используйте лучший инструмент для работы. Некоторые ситуации требуют использования статических массивов, а некоторые — динамических. Когда ситуация требует динамического массива, вместо этого используйте вектор.

Марк Ингрэм прав, что вы можете использовать wstring, но только если wchar_t имеет тот же размер, что и WCHAR.

Что-то вроде этого лучше подходит для того, что вы хотите (обратите внимание, я не запускал приведенное ниже через компилятор, потому что существует слишком много специфических конструкций Microsoft):

WCHAR sPath[MAX_PATH]; // doesn't need to be a dynamic array, so don't bother with a vector.
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, &sPath[0] );

const WCHAR sThemesPath[] = _T("\\Microsoft\\Windows\\Themes"); // doesn't need to be a dynamic array, so don't bother with a vector.
const WCHAR sFileName[] = _T("\\darkblue.theme"); // doesn't need to be a dynamic array, so don't bother with a vector.
vector<WCHAR> sOutput; // this needs to be dynamic so use a vector.

// wcslen should probably be replaced with an MS specific call that gets the length of a WCHAR string
copy(sPath, sPath + wcslen(sPath), back_inserter(sOutput));
copy(sThemesPath, sThemesPath + wcslen(sThemesPath), back_inserter(sOutput));
copy(sFlieName, sFileName + wcslen(sFileName), back_inserter(sOutput));
person Daniel T.    schedule 18.04.2011