в отдельном h-файле объявлен класс:
class A;
в потоке №2 создаются экземпляры этого класса:
h-файл:
private:
vector1 < A*>;
vector2 < A*>;
vector3 < A*>; // создаем три массива указателей на объекты
public:
vector4 < A*>;
cpp-файл: здесь выполняются операции следующего рода:
vector3.push_back(new A()); // создание объектов
vector2.push_back(vector3.back()); //
vector3.back()=0;
...
vector1[i]=vector2[j];
...
vector4.push_back(vector1[k]);
// после нулевые указатели удаляются из векторов
// содержимое всех векторов активно меняется
здесь первый вопрос: правомерно ли таким образом "передавать объект" из вектора в вектор. идея такая, что нужен доступ к объекту, причем только из одного вектора (значит в двух остальных указателей быть не должно).
далее в GUI-потоке:
объявлен класс:
class B //в конструкторе указатель на класс A
{
public:
B(A* p){
k=p; // получаем доступ к объекту
};
private:
A *k;
}
...
B fm = new B(*thread2->vector4[i]); // так создаем экземпляры класса B
...
второй вопрос: правильно ли таким образом получать доступ к i-му объекту?
компилятор ошибок не дает, программа запускается, но есть ошибки в логике.
такое подозрение, что k(private-член класса B) ссылается на те поля в памяти, которые заняты другим "не родным объектом".
Здравствуйте, Аноним, Вы писали:
А>здесь первый вопрос: правомерно ли таким образом "передавать объект" из вектора в вектор. идея такая, что нужен доступ к объекту, причем только из одного вектора (значит в двух остальных указателей быть не должно).
вопрос — зачем передавать обьекты из вектора в вектор?
изначально чтото с архитектурой совсем неправильно ... т.е. совсем совсем совсем неправильно
во вторых вы не передаете объект, а лишь плодите
указатели на обьект — это разные вещи ... если уж хотите иметь указатель в единственном екземпляре — uniq_ptr
А>А>class B //в конструкторе указатель на класс A
А> {
А> public:
А> B(A* p){
А> k=p; // получаем доступ к объекту
А> };
А> private:
А> A *k;
А> }
А>...
А>B fm = new B(*thread2->vector4[i]); // так создаем экземпляры класса B
А>...
А>
Какой смысл существования класса B ?
и что такое thread2 ?
Здравствуйте, Аноним, Вы писали:
<>
Тут слишком много всего, чтобы можно было быстро разобраться.
Заострю внимание на следующих вещах.
1) Владение объектами, и передача владения между владельцами.
В принципе, нет ничего сложного сделать всё это вручную:
old_pointer = new A;
...
new_pointer = old_pointer; old_pointer = 0;
...
delete new_pointer;
(как это сделано с .back() всех этих векторов).
Только две проблемы
— нужно ОЧЕНЬ тщательно следить за логикой, чтоб ничего не перепутать
— в исключительных ситуациях (в прямом смысле: если возникнет исключение) ручная передача владения может сломаться на полдороги, и там требуется тоже ОЧЕНЬ тщательно следить за обработкой исключений.
Умные указатели — shared_ptr, unique_ptr — сильно облегчают жизнь, но за логикой всё равно нужно послеживать. По крайней мере, за смыслом происходящего, а не за техническими подробностями (сюда записали, это обнулили строго после записи, здесь исключения не бывает, а здесь нужно ловить...)
2) Многопоточность.
Операции над векторами — а тем более, операции по переносу значения из вектора в вектор, — не атомарны.
Это значит, что пока один поток выполняет эту операцию, другой может вломиться и прочитать, а то и записать, несогласованное состояние.
Выход — расставить критические секции в коде и защитить их мьютексами. В виндах легковесный мьютекс так и называется — CRITICAL_SECTION. (Про линуксовские фьютексы ничего сказать не могу).
Критическая секция — это участок кода (или семейство участков кода), который одномоментно выполняется не более чем одним потоком. Ну и, соответственно, множество данных (с которыми этот код работает), к которым одномоментно может обращаться только один поток.
Обращение к каждому вектору, с которым имеют дело оба потока (я так понимаю, vector4) — в крит.секцию.
Перенос объекта или множества объектов в этот vector4 — в крит.секцию.
Если экземпляров vector4 несколько — то можно защитить каждый из них независимо.
А можно и по-военному, ввести один большой мьютекс на всю программу
Устроишь тормоза, зато избежишь проблем взаимоблокировки.