Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Копирование структур  (Прочитано 42830 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ezus
Опытный

il
Offline Offline

« : 17-05-2010 13:21 » 

Есть код в среде: VS C++ 6.0  &  MFC
Код:
struct Sa
{ int ia;
} sa;

struct Sb : public Sa
{ int ib;
} sb;

void ff(Sa* aa)
{ (Sa)sb = (*aa);   // Op1
(Sa)sb = sa;        // Op2
}

void tst()
{ sa.ia = 5;
ff(&sa);
}

Компиляция проходит, но присвоения данных в функции ff не происходит ни в Op1, ни в Op2.

Ясно, что я чего-то не понимаю.
Может быть кто-нибуть объяснит мне ЧТО?

Спасибо.

Записан
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #1 : 17-05-2010 13:25 » 

ezus, может, нужно перегрузить оператор =() для структуры ?
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
ezus
Опытный

il
Offline Offline

« Ответ #2 : 17-05-2010 13:32 » 

может, нужно перегрузить оператор =() для структуры ?
Как я понимаю - перегрузить оператор =() означает поэлементное переписывание, а именно этого я и пытаюсь избежать
Записан
baldr
Команда клуба

cy
Offline Offline
Пол: Мужской
Дорогие россияне


WWW
« Ответ #3 : 17-05-2010 13:34 » 

ezus, а как иначе можно скопировать сложный объект кроме как скопировать все его составляющие?
Есди б это был .NET, то там такой фокус удался бы.. В твоем случае (структура) было бы копирование, а если б это были объекты, просто было бы присвоение ссылки на один и тот же объект.
Записан

Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
ezus
Опытный

il
Offline Offline

« Ответ #4 : 17-05-2010 13:40 » 

Я исходил из того, что
Код:
struct Sa a1;
struct Sa a2;
....
a2 = a1;
Это легитимно и работает.
Записан
ezus
Опытный

il
Offline Offline

« Ответ #5 : 17-05-2010 13:41 » 

Может быть как-то по другому надо приводить наследующий класс к родительскому?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 17-05-2010 13:55 » 

А мне такой дизайн категорически не нравится, где в переменную sb(ia, ib) присваивается значение sa(ia), при этом поле ib остаётся неопределённым, что является потенциальным источником ошибок.

Правильно будет делать наоборот:
Код:
Sb *psb = dynamic_cast<Sb *>(&sa);
if(psb != NULL)
{
  sb = *psb;
}
При этом psb благополучно будет равно NULL - именно потому, что приведение типов некорректно.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 17-05-2010 13:55 » 

Код:
void ff(Sa* aa)
{
    static_cast<Sa&>(sb) = *aa;   // имхо, более джедайский путь
    (Sa&)sb = *aa;  // ну или так
}
Записан
ezus
Опытный

il
Offline Offline

« Ответ #8 : 17-05-2010 14:21 » 

Код:
void ff(Sa* aa)
{
    static_cast<Sa&>(sb) = *aa;   // имхо, более джедайский путь
    (Sa&)sb = *aa;  // ну или так
}
И то и другое по нулям - не работает.
Записан
ezus
Опытный

il
Offline Offline

« Ответ #9 : 17-05-2010 14:22 » 

Правильно будет делать наоборот:
Код:

Sb *psb = dynamic_cast<Sb *>(&sa);
if(psb != NULL)
{
  sb = *psb;
}

Получаю при компиляции
dynamic_cast : 'Sa' is not a polymorphic type
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 17-05-2010 14:26 » 

И то и другое по нулям - не работает.
"А у меня всё работает" (c)
Тогда меняй компилятор. Потому что cast-ы для ссылочных типов по стандарту должны давать l-value (а для не-ссылочных - r-value, поэтому твой вариант не заработал бы).

Или пиши извращения в духе
Код:
*(Sa*)&sb = *aa;
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 17-05-2010 14:29 » 

любители помудрить собрались )))
Код:
struct Sa
{ int ia;
};


struct Sb : public Sa
{
int ib;
void operator=(const Sa& sa_)
{
*((Sa*)this)=sa_;
}
};

Sa sa;
Sb sb;

void ff(const Sa& aa)
{ sb = aa;   // Op1
sb = sa;    // Op2
}

void tst()
{ sa.ia = 5;
ff(sa);
}
(не тестировал)
Записан

ezus
Опытный

il
Offline Offline

« Ответ #12 : 17-05-2010 14:37 » 

М..н..да!!!
Без поллитры..., а на работе низя.
Извращение чистого разума - одно слово С++.

А ведь еще в доисторическом коболе структуры можно было присваивать по совпадению имен переменных.

Всем спасибо.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 17-05-2010 14:49 » 

ezus, смотря, что считать тут извращением: присвоение вида (type b:public type a) = (type a) или специально написанный оператор присваивания, который является следствием первого извращения ))

И при этом сам вовсе не является извращением только потому, что так сказал Вад.
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 17-05-2010 17:47 » 

Цитата: ezus
Получаю при компиляции
dynamic_cast : 'Sa' is not a polymorphic type
Логично, у типа Sa нет таблицы виртуальных функций. Добавь пустой виртуальный деструктор, типа:
Код: (C++)
struct A
{
  int a;
  virtual ~A() {}
};
и всё будет.

P.S. Но кривости дизайна это не отменяет.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
ezus
Опытный

il
Offline Offline

« Ответ #15 : 17-05-2010 20:24 » 

С мой точки зрения - все эти варианты близки к извращениям.

Но это мои личные недостатки. Дело в том, что ответ на вопрос КАК, т.е. непосредственно кодирование с его триками, увлекал меня только первые 10-12 лет, а затем он интересовал меня только с точки зрения решения конкретных задач. Поэтому я оцениваю любой инструмент исключительно с позиции близости к предметной области, а все трюки и трики меня только раздражают.

Все это старческий маразм и я извиняюсь перед приверженцами С++.
Я очень любил и люблю чистый С. Но С++ - извините - только по необходимости.

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

Спасибо за помощь.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 17-05-2010 21:48 » 

Цитата: ezus
Поэтому я оцениваю любой инструмент исключительно с позиции близости к предметной области, а все трюки и трики меня только раздражают.
Меня тоже раздражают трюки - люблю ясные и простые решения. Но дизайн твоего кода ярко демонстрирует, что у тебя нет вменяемого описания предметной области. То, что ты пытаешься делать, это форменное надругательство над логикой. И именно чтобы прикрыть это надругательство над логикой, тебе понадобились все те пляски с бубном, которые тебе тут предложили.

Был бы это не C/C++, а, допустим, Ada или Eiffel, у тебя не осталось бы ни одного шанса выкрутиться - пришлось бы менять дизайн.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 18-05-2010 03:41 » 

ezus, возможно, тебе нужно вообще вот так было ? Проще некуда

Код:
struct Sa
{
int ia;
};

struct Sb
{
Sa aa;
int ib;
};

Sa sa;
Sb sb;

void ff(const Sa& aa)
{ sb.aa = aa;   // Op1
sb.aa = sa;    // Op2
}

void tst()
{ sa.ia = 5;
ff(sa);
}
Записан

sss
Специалист

ru
Offline Offline

« Ответ #18 : 18-05-2010 05:29 » 

ezus, а вы вообще чего хотели добиться оператором (Sa)sb = (*aa) ? Присвоить член Sb::ib члену Sa::ia или ... почему тогда не получилось? Как вы  проверяете что не получилось?

Это что то из разряда
Код:
  char x = (char) 0xFF00;
Объясните ЧТО
 
Записан

while (8==8)
ezus
Опытный

il
Offline Offline

« Ответ #19 : 18-05-2010 07:49 » 

а вы вообще чего хотели добиться оператором (Sa)sb = (*aa) ? Присвоить член Sb::ib члену Sa::ia
Конечно - нет.
Цитата
Как вы  проверяете что не получилось?
Пошаговым Дебагом.
Цитата
Объясните ЧТО
Я попытался это сделать в предыдущем посте.
Записан
ezus
Опытный

il
Offline Offline

« Ответ #20 : 19-05-2010 07:43 » 

Если у тебя ZSysVectorSimulation паблик от  ZSysVector (читай: содержит в начале себя структуру  ZSysVector ), то всё равно тебе туда копировать извне. Какая разница как? Оператор ли "=", конструктор ли, memmove, чёрт побери ))
Так в том и вопрос - КАК? Как переписать содержимое базовой части не перечисляя ее переменные?

Я и не думал, что мой примитивный вопрос КАК вызовет такую дискуссию.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 19-05-2010 07:50 » 

Цитата
Так в том и вопрос - КАК? Как переписать содержимое базовой части не перечисляя ее переменные?

если не поддержан оператор "=", и возможно безболезненное побайтовое копирование, то просто ... побайтово скопировать ))

Sa s1,s2;
memmove(&s1,&s2,sizeof(s1));

Цитата
Я и не думал, что мой примитивный вопрос КАК вызовет такую дискуссию.
вообще-то, это уже ответы на другие вопросы, так как первый вопрос был
Цитата
Компиляция проходит, но присвоения данных в функции ff не происходит ни в Op1, ни в Op2.
Ясно, что я чего-то не понимаю.
Может быть кто-нибуть объяснит мне ЧТО?

а там была ошибка:

(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa
« Последнее редактирование: 19-05-2010 08:02 от Алексей1153++ » Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #22 : 19-05-2010 08:41 » 

(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa

именно это и происходит

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

PS:
да, я вернулся Улыбаюсь
« Последнее редактирование: 19-05-2010 08:44 от LogRus » Записан

Странно всё это....
sss
Специалист

ru
Offline Offline

« Ответ #23 : 19-05-2010 08:52 » 

Жаль.
Записан

while (8==8)
ezus
Опытный

il
Offline Offline

« Ответ #24 : 19-05-2010 09:27 » 

если не поддержан оператор "=",
Этого нет.
Цитата
и возможно безболезненное побайтовое копирование, то просто ... побайтово скопировать ))

Sa s1,s2;
memmove(&s1,&s2,sizeof(s1));
А черт его знает безболезненно или нет. Вот я и хотел сделать это средствами языка, а не ассемблера. Улыбаюсь

Цитата
Цитата
Компиляция проходит, но присвоения данных в функции ff не происходит ни в Op1, ни в Op2.
Ясно, что я чего-то не понимаю.
Может быть кто-нибуть объяснит мне ЧТО?

а там была ошибка:

(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa
(Sa)sb - я считал это просто указанием компилятору о приведении типа. Наверное был не прав.
Скорей всего это наследие Java, в которой такие вещи делаются просто.
(Только не надо дискуссий о том, кто хорошо, а кто плохо  Улыбаюсь )
Записан
ezus
Опытный

il
Offline Offline

« Ответ #25 : 19-05-2010 09:30 » 

(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa

именно это и происходит
А есть какие-то другие решения кроме memcopy?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 19-05-2010 09:31 » 

ezus, да, их в этой теме показывали не один человек и не раз, если не путаю ))
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #27 : 19-05-2010 09:40 » 

(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa
именно это и происходит
А есть какие-то другие решения кроме memcopy?

читайте тему с начала
решение уже было:
Код:
(Sa&)sb = sa;
Записан

Странно всё это....
ezus
Опытный

il
Offline Offline

« Ответ #28 : 19-05-2010 09:44 » 

решение уже было:
Код:
(Sa&)sb = sa;
Почему то у меня не сработало.
Спасибо - еще раз проверю.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #29 : 19-05-2010 09:46 » 

у меня сработало (проверил на всякий случай, вдруг я не прав)
компилятор из VC++2003
Записан

Странно всё это....
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #30 : 19-05-2010 11:55 » 

разрезал тему на две: размышления об ООП переехали сюда https://forum.shelek.ru/index.php/topic,24490.0.html
Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #31 : 19-05-2010 12:07 » 

Ну там не только размышления об ООП. Там в том числе и объяснение того, почему желаемое автором не работает.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines