Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Копирование объектов в Multithreading, Копирование объектов с массивом объектов 
V
    Опции темы
exploys
Дата 20.10.2010, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.4.2009

Репутация: нет
Всего: нет



Упрощенный пример
Код


class MyClassA
{
 public:
 class MyClassB
 {
  int Par1;
  char Par2;
 }

 int ParA;
 MyClassB *MyObjectsB;
 unsigned int CountMyObjects;

 void initFromFile(string fileName)
 { .... }
};

MyClassA objectA1;

int main(int argc, char* argv[])
{
 objectA1.initFromFile("fileName");
}

void MyFunc(void)
{
 MyClassA objectA2;
 objectA2 = objectA1; 
}


И собственно два вопроса:
1. Как лучше сделать чтобы при objectA2 = objectA1; копировались не указатели на MyObjectsB, а создавалась собственная копия MyObjectsB для objectA2. Перегрузкой оператора =, отдельной функцией или как-то ещё.
2. При условии, что функция void MyFunc(void) будет вызываться из множества потоков что следует исправить в коде?

Подскажите что исправить или посоветуйте литературу, а если и то и то, то вообще будет шикарно.


PM MAIL   Вверх
Rad87
Дата 20.10.2010, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 26.7.2010

Репутация: нет
Всего: нет



вероятно, описать все это в конструкторе копирования
PM MAIL   Вверх
xvr
Дата 20.10.2010, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(exploys @ 20.10.2010,  01:22)
1. Как лучше сделать чтобы при objectA2 = objectA1; копировались не указатели на MyObjectsB, а создавалась собственная копия MyObjectsB для objectA2. Перегрузкой оператора =, отдельной функцией или как-то ещё.

Оператор присваивания и конструктор копирования
Цитата

2. При условии, что функция void MyFunc(void) будет вызываться из множества потоков что следует исправить в коде?

Целиком зависит от содержимого этой функции (т.е. от того самого оператора присваивания и конструктора копирования).
Самый универсальный способ - критическая секция (но и самый не эффективный по производительности)


Это сообщение отредактировал(а) xvr - 20.10.2010, 09:06
PM MAIL   Вверх
GremlinProg
Дата 20.10.2010, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ну да, вот, кстати xvr тут где-то приводил вариант прокси с критической секцией,
удобнее похоже и не придумать

а вот по производительней можно использовать дроссель из семафора,
который будет перекрываться полностью при изменении каких-либо указателей (критические изменения в объекте),
или просто приоткрываться для определенного потока, если надо его только скопировать

единственное, что тут надо предусмотреть, чтобы полное перекрытие было защищено критической секцией,
чтобы несколько потоков не могли одновременно вносить критические изменения в объект

если сильно интересно, то почитать об этом можно у Харта, например: http://www.williamspublishing.com/Books/5-8459-0879-5.html


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
exploys
Дата 20.10.2010, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.4.2009

Репутация: нет
Всего: нет



Спасибо за подсказки.

Создал функцию глубокого копирования  void Copy(MyClassA src) и конструктор копирования использующий данную функцию. Здесь все понятно. 

Вопрос для полноты понимания: как перегрузить оператор = для глубокого копирования (чтобы не перечислять все члены класса, а только те которые нужно скопировать по указателям, как в конструкторе копирования)?
Пробовал не получается.

Код


class MyClassA
{
 public:
 class MyClassB
 {
  int Par1;
  char Par2;
 }
 int ParA;
 MyClassB *MyObjectsB;
 unsigned int CountMyObjects;
 void initFromFile(string fileName)
 { .... }

 // Глубокое копирование
 void Copy(MyClassA src)
 {
  // поверхностное копирование
  *this = src;

  // глубокое копирование массива MyObjectsB[]
  this->MyObjectsB = new MyClassB [src.CountMyObjects];
  for (unsigned int indexObjectsB = 0; indexObjectsB < src.CountMyObjects; indexObjectsB ++)
   this->MyObjectsB[indexObjectsB ] = src.MyObjectsB[indexObjectsB ];
 }

 // Конструктор копирования с глубоким копированием
 MyClassA::MyClassA(MyClassAconst& src)
 {
   Copy(src);
 }
};

MyClassA objectA1;
int main(int argc, char* argv[])
{
 objectA1.initFromFile("fileName");
}
void MyFunc(void)
{
 MyClassA objectA2;
 objectA2 = objectA1;  // Поверхностное копирование
 objectA2.Copy(objectA1);  // Глубокое копирование
 MyClassA objectA3 = objectA1; // Глубокое копирование
}



Цитата(GremlinProg @  20.10.2010,  08:34 Найти цитируемый пост)

если сильно интересно, то почитать об этом можно у Харта, например: http://www.williamspublishing.com/Books/5-8459-0879-5.html 

Спасибо буду изучать.
А не подскажите как найти "вариант прокси с критической секцией от xvr"?
PM MAIL   Вверх
GremlinProg
Дата 20.10.2010, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(exploys @  20.10.2010,  22:40 Найти цитируемый пост)
как найти "вариант прокси с критической секцией от xvr"?

1. нажать "поиск"
2. ввести ключевое слово proxy
3. ввести в "фильтр по имени пользователя" xvr
4. нажать "найти"


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
xvr
Дата 20.10.2010, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



PM MAIL   Вверх
exploys
Дата 29.11.2010, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.4.2009

Репутация: нет
Всего: нет



Спасибо. Классная штука.
А при перегрузке оператора = обязательно придется прописывать копирование каждой переменной или можно как-то их скопом скопировать? (а затем уже с нужными объектами провести глубокое копирование)
PM MAIL   Вверх
xvr
Дата 29.11.2010, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(exploys @  29.11.2010,  10:45 Найти цитируемый пост)
А при перегрузке оператора = обязательно придется прописывать копирование каждой переменной или можно как-то их скопом скопировать?
В очень редких случаях можно сделать memcpy(this,other,sizeof(*this));. Но это очень опасно, и если есть сомнения, то лучше так не делать!


PM MAIL   Вверх
exploys
Дата 1.12.2010, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.4.2009

Репутация: нет
Всего: нет



Цитата(xvr @ 29.11.2010,  11:20)
Цитата(exploys @  29.11.2010,  10:45 Найти цитируемый пост)
А при перегрузке оператора = обязательно придется прописывать копирование каждой переменной или можно как-то их скопом скопировать?
В очень редких случаях можно сделать memcpy(this,other,sizeof(*this));. Но это очень опасно, и если есть сомнения, то лучше так не делать!

Я тоже подумал, что это некий костыль. А адекватного способа так и не нашел.
Т.е. либо полностью отдавать на откуп компилятору который почленно произведет поверхностное копирование. Либо делать глубокое, но уже самому почленно все прописывать. Оба варианта не всегда подходят.
Как вариант использовать умные указатели и контейнеры.
PM MAIL   Вверх
GremlinProg
Дата 1.12.2010, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(exploys @  1.12.2010,  13:33 Найти цитируемый пост)
А адекватного способа так и не нашел

адекватный - не переписывать оператор =
в этом случае все данные копируются почленно автоматом

Добавлено @ 11:45
если надо совместить почленное и глубокое копирование, то используется наследование:
Код

class B : public A{
  ...
  B&operator = ( const B&Src ){
    static_cast< &A >( *this ) = static_cast< const &A >( Src );
    //  ...глубокое копирование
    return *this;
  }
  ...
};

в классе A должны быть объявлены все данные для почленного копирования,
в классе A не должен быть переписан оператор =

Добавлено @ 11:50
кстати, тема подходит больше для раздела C/C++: Общие вопросы, перенести?

хотя, ладно, раз Multithreading, пусть тут живет

Это сообщение отредактировал(а) GremlinProg - 1.12.2010, 12:00


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
exploys
Дата 10.12.2010, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.4.2009

Репутация: нет
Всего: нет



Спасибо, то что нужно smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1216 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.