Archive for the ‘C++’ Category.
30th March 2008, 03:06 pm
Мне достаточно часто необходимо переключаться между H и CPP файлами в процессе разработки. На работе обычно у меня стоит Visual Assist X, для которого это одна из многих опций. Но вот понадобилось сделать тоже самое, но без Visual Assist X, борьба за использование только лицензионного ПО. В 2005 студии есть набор макросов,один из которых умеет переключаться между H и CPP, а вот в 2003 не нашел. Поискал в интернете и нашел этот макрос.
Sub GetFriendFile()
'DESCRIPTION: Opens the corresponding .h / .cpp file
Dim currentFileName As String
Dim newFileName As String
currentFileName = Application.ActiveDocument.FullName
newFileName = ""
If (UCase(Right(currentFileName, 2)) = ".H") Then
newFileName = Left(currentFileName, Len(currentFileName) - 2) + ".CPP"
ElseIf (UCase(Right(currentFileName, 4)) = ".CPP") Then
newFileName = Left(currentFileName, Len(currentFileName) - 4) + ".H"
End If
If newFileName <> "" Then Application.Documents.Open(newFileName)
End Sub
Для того чтобы его использовать идете в Tools | Macros | Macros IDE появится новое окно в котором будет открыт MyMacros проект. Добавьте новый модуль, назовите его скажем Switch2cpp. И далее вставьте в него функцию GetFriendFile, сохраните и затем назначьте сочетание клавиш.
Для этого выберите Tools|Options|Environment|Keyboard и там выберите из лист бокса Macros.MyMacros.Switch2cpp.GetFriendFile и сочетание клавиш, которые будут выполнять данный макрос, после этого не забудьте нажать кнопку Assign - наслаждайтесь.
Материал испльзуемый при написании поста:
28th January 2008, 01:37 pm
На работе в проекте используется MFC, причем везде и много. При запуске иногда программа серьйозно притормаживает. Натравить профайлер не могу, BoundChecker просто загнулся, а остальные я не пробовал, т.к руководству это не нужно и, соответственно, времени отпрофайлить мне никто не даст. Так вот, найдя проблемный участок кода, я обнаружил, что там происходит вставка элементов в CMap (класс MFC реализованный с помощью хеш-массива ) , причем при увеличении кол-ва элементов, время на вставку возростало. Попрошу извинить меня за предложения типа "при увеличении кол-ва элементов, время на вставку возростало" , из отсутствия профайлера я более точно сказать не могу, в проекте все замерял на глаз. Но эти наблюдения сподвигли меня написать маленький тест по сравнению производительности STL и MFC.
Тест достаточно простой - вставка элементов в CMap, std::map и stdext::hash_map. С помощью кода ниже я нагенерировал неповторяющиеся последовательноси символов
void GenerateSequence(const std::string& file_name,int nNumCh)
{
if(nNumCh>16)
return;
char buf[]="0123456789abcdefg";
std::string sRealStr(buf,buf+nNumCh);
int nCount=0;
std::ofstream f(file_name.c_str(),std::ios::out|std::ios::trunc);
while(std::next_permutation(sRealStr.begin(),sRealStr.end()))
{
++nCount;
f<<" "<<sRealStr;
if(!(nCount%15))
f<<std::endl;
}
}
тестировал на последовательностях из 6,7,8 и 9 символов, соответственно 720, 5040, 40320 и 362880 элементов. Результаты приведены ниже в виде таблицы и диаграммы, время в секундах
|
STL map |
MFC map |
Initialized MFC map |
STL hashmap |
| 719 |
0.0006866790 |
0.0004520130 |
0.0003318860 |
0.0004151370 |
| 5039 |
0.00598372 |
0.00580493 |
0.00249222 |
0.00312610 |
| 40319 |
0.07176890 |
0.69810400 |
0.02297470 |
0.02608380 |
| 362879 |
0.77434000 |
241.62900000 |
0.24009400 |
11.61740000 |

Пару слов о легенде, думаю не совсем понятно, что такое Initialized MFC map - это перед использованием CMap контейнер инициализируется количеством элементов которые в него вставят.После этого теста многое стало на свои места - мы используем тот случай, который имеет самый высокий столбец на графике. Вот так вот ...
18th January 2008, 12:08 am
Довольно часто приходться сериализовать\десериализовать объекты например при передачи их по сети. Вместо того, чтобы передавать MessageID и потом, расспознав его, принимать остальную часть сообщения, можно использовать библиотеку которая будет выполнять эту работу сама. Одной из библиотек котороя обладает вышеописанной функциональностью является boost::serialization По ссылке находится вполне исчерпывающая документация, но я столкнулся со сложностью и внятного ответа в документации не нашел. Проблема была в следующем, хотелось бы иметь возможность передавать по сети объекты наследованные от какого-нибудь базового класса и затем десериализовать их через указатель на базовый класс. Например:
class Base
{
};
class Derived:public Base
{
int nValue;
};
//....
void save()
{
Base* pDerived = new Derived;
binarystream_out << pDerived;
};
void load()
{
Base* pDerived = 0;
binarystream_in >> pDerived;
};
Проблема заключается в том, что при десериализации член nValue класса Derived не будет корректно десериализован, он будет содержать какой-то мусор. В примерах к библиотеке эта проблема решается оригинальным способом, первый раз десериализовать объект явно указав его тип.
void load()
{
Derived* pDerived ;
binarystream_in >> pDerived;
//после этого класс регистрируется и ниже в коде можна вызывать
Base* pDerived2;
binarystream_in >> pDerived2;
//десериализация проходит корректно
};
Наверное нелишним будет упомянуть, что я столкнулся с этой же ситуацией в MFC и долго просидел в дебагере пока понял что не так.
Проблема решается достаточно просто, достаточно зарегистрировать класс в input stream.
void load()
{
Base* pDerived ;
binarystream_in.register_type(static_cast<Derived*>(0));
binarystream_in >> pDerived;
};
boost::serialization example