Тазом чувствую, что что-то неправильно, а что -- понять не могу:
void __fastcall MergeDataSets(TOAClientDataSet* cdsDst, TOAClientDataSet* cdsSrc, std::vector<const char*>& KeyFieldNames, std::vector<const char*>& CopyFieldNames)
{
//собираю ключи, которые уже есть в датасете назначения
std::set<std::vector<AnsiString> > existing_keys;
for (cdsDst->First(); !cdsDst->Eof; cdsDst->Next())
existing_keys.insert(CreateKeyVector(cdsDst, KeyFieldNames)); //функцию смотри ниже
for (cdsSrc->First(); !cdsSrc->Eof; cdsSrc->Next())
{
//проверяю, что ключ из второго датасета не встречается в первом
std::vector
if (existing_keys.find(key) == existing_keys.end())
{
//копирую из второго в первый
//...
existing_keys.insert(key);
}
}
while (!existing_keys.empty())
{
//как бы, наверно, надо зачистить память, да?
existing_keys.begin()->clear();
existing_keys.erase(existing_keys.begin());
}
}
Ключ -- это вектор, строящийся из строчных представлений значений полей, имена которых перечислены в векторе KeyFieldNames, порядок, естественно, важен.
std::vector
{
unsigned key_length = KeyFieldNames.size();
std::vector<AnsiString> key;
for (unsigned i = 0; i < key_length; i++)
key.push_back(cds->FieldByName(KeyFieldNames[i])->AsString);
return key;
}
И вот подсказывает мне мой таз, что то ли память не зачищается где-то, то ли наоборот, объект удалится раньше, чем ссылки перестанут быть нужны.
no subject
Хм... а где дебагер падает?
no subject
А виртуальными функциями пользоваться в темплейтах нельзя-я.
no subject
Во-вторых, здесь проблема куда серьезней: existing_keys не имеет оператора сравнения для его членов (в твоем случае это vector
Во-вторых, здесь проблема куда серьезней: existing_keys не имеет оператора сравнения для его членов (в твоем случае это vector<char*>). Кто сказал, что вектора равны, когда имеют одинаковую начинку. О правильном использовании std::set и задавании оператора сравнения для членов см. http://www.sgi.com/tech/stl/set.html
В третьих, кто сказал что виртуальными функциями пользоваться в темплейтах нельзя?
А в-четвертых, за такие постинги, тебя конечно следует разфрендить! :))
no subject
2. А в хелпе написано, что у векторов есть оператор сравнения. Правда, как он работает, там не написано, но я почему-то решил, что именно так, как мне надо -- почленно.
3. Компилятор сказал. Я подумал, что, если проблема в том, что у разных датасетов разные ключи, то проблему решат
class KeyGenerator
{
public:
virtual Key GenerateKey(TOAClientDataSet* cds)=0;
}
class Key
{
public:
bool ExistsIn(std::set& keys)
{
for (std::set::iterator iter = keys.begin(); iter != keys.end(); ++iter)
if (!this->operator==(*iter))
return true;
return false;
}
//естественно,
virtual bool operator==(Key&)=0;
};
а от них уже наследовать хреновины для конкретных датасетов. И все было бы прекрасно, да нельзя, оказывается, темплейтным аргументам виртуальные функции пользовать.
4. "А кому смотреть противно, тот пускай и не глядит. Мы же в нос к нему не лезем? Пусть и он не пристает."
no subject
2. Esli v helpe napisano to togda tochno vse ok, t.k. drugovo logichnogo operatora == dlia vectora pridumat slozno.
3. Aga, reshat.
no subject
no subject
1) На стеке функции CreateKeyVector создается обьект key.
2) key возвращается в MergeDataSets
3) Обьект разрушается по завершении функции MergeDataSets (вызывается деструктор std::set к-рый заодно чистит его содержимое перед удалением обьекта).
2. Встроенный оператор сравнивания для вектора определен. Но я бы не стал на него полагаться. В нашем случае мы заносим char*, то есть поинтеры, которые равны только при равенстве самого физического адреса. Грубо, следуещее не всегда верно: ("Дима" == "Дима").
3. А вот компилятору верю! К тому же твое решение подходит и вполне красиво.
4. Шутка.
no subject
3. Нет, оно подходит, конечно, но неосуществимо, поскольку классы с виртуальными абстрактными функциями не могут использоваться как темлпейтные аргументы. По крайне ймере, так говорит компилятор.
4. Шутки шутками, а отписываться от меня народ начал. Не вынесла душа поэта, типа.
no subject
#include
using namespace std;
template
void f(T& obj) {
obj.f();
}
class A {
public:
virtual void f() = 0;
};
class B : public A {
public:
virtual void f() { cerr << "B\n"; }
};
void g(A& obj) {
f(obj);
}
int main() {
A* b = new B;
g(*b);
}
4. мстительно слежу за тем, как отписавшиеся от меня окружающие переживают из-за сокращения собственных френд-оф списков.
no subject
4. Никогда не понимал, почему внимание или невнимание его мыслям должно расцениваться человеком как знак поощрения или наоборот... Мысли замерзли с утра, не получается.
no subject
Скорее всего, ты попытался хранить абстрактный класс "by value", а это -- грех.
4. Так как любой активный ЖЖ пишется для читателей, расширение аудитории показывает писателю, что его старания не пропадают даром. Соответственно, уменьшение аудитории действует в обратную сторону, утверждая что писанина -- скучная и никому не интересная.
no subject
no subject
Чего тогда не пишешь в ноутпад, сохраняя в трипл-дес на флеш-карте, оснащенной биометрической защитой?
no subject
Мне честно нет никакого дела до того, двести человек меня читают или двадцать. Числа приобретают значение, когда сопрягаются с другими числами: скажем, когда нужно повысить шансы найти какую-нибудь хрень по людям, получить совет или помощь. В этом смысле в фидо было лучше: были целевые эхи с толпой народа, и были общательные, где толпа не имела значения.
no subject
no subject
А насчет (4) - я до сегодняшнего дня думал, что больше компилятору моего визуального восприятия никогда не предстанет токен TOAClientDataSet !!! :)))
no subject
Вообще говоря, на множествах у нас есть стандартные операции типа set_union, set_intersection etc. Раз уж танцуем в сторону красивого кода, надо б о них подумать. Добавить генератор, построить два множества, и их объединить. Кррррасота. И дико медленно.
no subject
no subject
Хотя -- я тут человек маленький, могу и поизвращаться в свое удовольствие, никто особенно не заметит, а мне приятно.