ezus
Опытный
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
|
|
« Ответ #1 : 17-05-2010 13:25 » |
|
ezus, может, нужно перегрузить оператор =() для структуры ?
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #2 : 17-05-2010 13:32 » |
|
может, нужно перегрузить оператор =() для структуры ?
Как я понимаю - перегрузить оператор =() означает поэлементное переписывание, а именно этого я и пытаюсь избежать
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #3 : 17-05-2010 13:34 » |
|
ezus, а как иначе можно скопировать сложный объект кроме как скопировать все его составляющие? Есди б это был .NET, то там такой фокус удался бы.. В твоем случае (структура) было бы копирование, а если б это были объекты, просто было бы присвоение ссылки на один и тот же объект.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #4 : 17-05-2010 13:40 » |
|
Я исходил из того, что struct Sa a1; struct Sa a2; .... a2 = a1;
Это легитимно и работает.
|
|
|
Записан
|
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #5 : 17-05-2010 13:41 » |
|
Может быть как-то по другому надо приводить наследующий класс к родительскому?
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
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 - именно потому, что приведение типов некорректно.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Вад
|
|
« Ответ #7 : 17-05-2010 13:55 » |
|
void ff(Sa* aa) { static_cast<Sa&>(sb) = *aa; // имхо, более джедайский путь (Sa&)sb = *aa; // ну или так }
|
|
|
Записан
|
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #8 : 17-05-2010 14:21 » |
|
void ff(Sa* aa) { static_cast<Sa&>(sb) = *aa; // имхо, более джедайский путь (Sa&)sb = *aa; // ну или так }
И то и другое по нулям - не работает.
|
|
|
Записан
|
|
|
|
ezus
Опытный
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
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #10 : 17-05-2010 14:26 » |
|
И то и другое по нулям - не работает.
"А у меня всё работает" (c) Тогда меняй компилятор. Потому что cast-ы для ссылочных типов по стандарту должны давать l-value (а для не-ссылочных - r-value, поэтому твой вариант не заработал бы). Или пиши извращения в духе *(Sa*)&sb = *aa;
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
Offline
|
|
« Ответ #12 : 17-05-2010 14:37 » |
|
М..н..да!!! Без поллитры..., а на работе низя. Извращение чистого разума - одно слово С++.
А ведь еще в доисторическом коболе структуры можно было присваивать по совпадению имен переменных.
Всем спасибо.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 17-05-2010 14:49 » |
|
ezus, смотря, что считать тут извращением: присвоение вида (type b:public type a) = (type a) или специально написанный оператор присваивания, который является следствием первого извращения ))
И при этом сам вовсе не является извращением только потому, что так сказал Вад.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #14 : 17-05-2010 17:47 » |
|
Получаю при компиляции dynamic_cast : 'Sa' is not a polymorphic type Логично, у типа Sa нет таблицы виртуальных функций. Добавь пустой виртуальный деструктор, типа: struct A { int a; virtual ~A() {} }; и всё будет. P.S. Но кривости дизайна это не отменяет.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #15 : 17-05-2010 20:24 » |
|
С мой точки зрения - все эти варианты близки к извращениям.
Но это мои личные недостатки. Дело в том, что ответ на вопрос КАК, т.е. непосредственно кодирование с его триками, увлекал меня только первые 10-12 лет, а затем он интересовал меня только с точки зрения решения конкретных задач. Поэтому я оцениваю любой инструмент исключительно с позиции близости к предметной области, а все трюки и трики меня только раздражают.
Все это старческий маразм и я извиняюсь перед приверженцами С++. Я очень любил и люблю чистый С. Но С++ - извините - только по необходимости.
Я очень надеюсь, что это заявление не изменит отношения уважаемых мной гуру данного форума к моим вопросам. Я их задаю, только когда мои попытки сформулировать адекватный вопрос к гуглу остаются без ответа, только тогда, когда упираюсь лбом в стенку.
Спасибо за помощь.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #16 : 17-05-2010 21:48 » |
|
Поэтому я оцениваю любой инструмент исключительно с позиции близости к предметной области, а все трюки и трики меня только раздражают. Меня тоже раздражают трюки - люблю ясные и простые решения. Но дизайн твоего кода ярко демонстрирует, что у тебя нет вменяемого описания предметной области. То, что ты пытаешься делать, это форменное надругательство над логикой. И именно чтобы прикрыть это надругательство над логикой, тебе понадобились все те пляски с бубном, которые тебе тут предложили. Был бы это не C/C++, а, допустим, Ada или Eiffel, у тебя не осталось бы ни одного шанса выкрутиться - пришлось бы менять дизайн.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Специалист
Offline
|
|
« Ответ #18 : 18-05-2010 05:29 » |
|
ezus, а вы вообще чего хотели добиться оператором (Sa)sb = (*aa) ? Присвоить член Sb::ib члену Sa::ia или ... почему тогда не получилось? Как вы проверяете что не получилось? Это что то из разряда char x = (char) 0xFF00;
Объясните ЧТО
|
|
|
Записан
|
while (8==8)
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #19 : 18-05-2010 07:49 » |
|
а вы вообще чего хотели добиться оператором (Sa)sb = (*aa) ? Присвоить член Sb::ib члену Sa::ia Конечно - нет. Как вы проверяете что не получилось? Пошаговым Дебагом. Объясните ЧТО Я попытался это сделать в предыдущем посте.
|
|
|
Записан
|
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #20 : 19-05-2010 07:43 » |
|
Если у тебя ZSysVectorSimulation паблик от ZSysVector (читай: содержит в начале себя структуру ZSysVector ), то всё равно тебе туда копировать извне. Какая разница как? Оператор ли "=", конструктор ли, memmove, чёрт побери ))
Так в том и вопрос - КАК? Как переписать содержимое базовой части не перечисляя ее переменные? Я и не думал, что мой примитивный вопрос КАК вызовет такую дискуссию.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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)
|
|
« Ответ #22 : 19-05-2010 08:41 » |
|
(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa
именно это и происходит Коллеги, призываю закончить офф-топик, проблема была во временной переменной, хотите подискутировать о проблемах проектирования и т.д. и т.п, идите в соответствующий раздел PS: да, я вернулся
|
|
« Последнее редактирование: 19-05-2010 08:44 от LogRus »
|
Записан
|
Странно всё это....
|
|
|
sss
Специалист
Offline
|
|
« Ответ #23 : 19-05-2010 08:52 » |
|
Жаль.
|
|
|
Записан
|
while (8==8)
|
|
|
ezus
Опытный
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
Опытный
Offline
|
|
« Ответ #25 : 19-05-2010 09:30 » |
|
(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa
именно это и происходит А есть какие-то другие решения кроме memcopy?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #26 : 19-05-2010 09:31 » |
|
ezus, да, их в этой теме показывали не один человек и не раз, если не путаю ))
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #27 : 19-05-2010 09:40 » |
|
(Sa)sb = sa;//разобрать не берусь, но что-то вроде создания на стеке безымянной переменной типа Sa с присвоением ей значения sa
именно это и происходит А есть какие-то другие решения кроме memcopy? читайте тему с начала решение уже было: (Sa&)sb = sa;
|
|
|
Записан
|
Странно всё это....
|
|
|
ezus
Опытный
Offline
|
|
« Ответ #28 : 19-05-2010 09:44 » |
|
решение уже было: (Sa&)sb = sa;
Почему то у меня не сработало. Спасибо - еще раз проверю.
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #29 : 19-05-2010 09:46 » |
|
у меня сработало (проверил на всякий случай, вдруг я не прав) компилятор из VC++2003
|
|
|
Записан
|
Странно всё это....
|
|
|
|