Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.19.27.178] |
|
Сообщ.
#1
,
|
|
|
Имеем два класса "b" и "c", оба наследники "a" и, соответственно, два объекта "B" и "C" этих классов.
class a { int A; }; class b: public a { int B; }; class c: public a { int C; }; b B; c C; Я хочу скопировать "а"-часть из объекта "С" в объект "B". Варианты (a)B = C и static_cast<a>(B) = C компилятся без ошибок, но не гегенрят ни одной команды кода. Варианты *(a*)&B = C и *static_cast<a*>(&B) = C; генерят необходимый код, но мне не понятно, чем они отличаются от (a)B = C и почему код (a)B = C выкидывается компилятором? |
Сообщ.
#2
,
|
|
|
Цитата Dushevny @ компилятся без ошибок, но не гегенрят ни одной команды кода. Скорее всего просто оптимизация. static_cast<a>(B) = C - создает временный объект типа a, скопированный из B, у временного объекта вызывается operator=(const A&), после чего объект сразу же уничтожается, не создавая никаких сайд-эфектов. Так как оператор у тебя тривиальный, то компилятор, наверно, считает, что это код ни на что не влияет и выкидывает его. Возможно (я плохо разбираюсь в оптимизациях которые делает компилятор), если ты определишь свой operator=, то код выбрасываться не будет, но в B нужного значения все равно не будет. делай так static_cast<a&>(B) = C; |
Сообщ.
#3
,
|
|
|
Да, похоже вы правы. Спасибо, с приведением к ссылке заработало.
|
Сообщ.
#4
,
|
|
|
Всё правильно. Приведение к значению создаёт rvalue. Нужно приведение к ссылке, тогда будет lvalue.
|
Сообщ.
#5
,
|
|
|
Но вообще, такое приведение в программе выглядит несколько неряшливо.
Не лучше ли определить для классов b и c оператор присваивания, принимающий объект класса a и изменяющий нужную часть? Хотя бы посредством того же *static_cast<a *>this = a_value; |
Сообщ.
#6
,
|
|
|
Да, согласен. Но у меня это не классы, а структуры, описывающие протокол обмена. И в них операторы смотрятся еще более неуместными, как мне кажется, поскольку являются частью реализации одной конкретной части системы из всех.
|
Сообщ.
#7
,
|
|
|
Тогда тем более непонятно использование для них слова class и наследования.
Правильнее, проще и понятнее было бы назвать эти структeры struct a, struct b, struct c, включить struct a в остальные в качестве первого члена и не извращаться с преобразованием типов ссылок/указателей. |
Сообщ.
#8
,
|
|
|
Цитата amk @ в данном случае включение противоречит концепции. Между а и b, a и c отношение "является" (is-a), а не "содержит" (has-a). И поскольку уровней наследования у меня сильно больше двух и они могут расти по мере добавления в протокол новых возможностей, а каждый родитель является, по сути, заголовком пакета для потомка - все это выливается в E.Header.Header.Header.Field_a, что совсем не способствует читаемости исходника. включить struct a в остальные в качестве первого члена и не извращаться |
Сообщ.
#9
,
|
|
|
Хозяин - барин. Можно подумать, static_cast<a&>(B) = C; делает код более удобочитаемым. Впрочем, наверно, эти действия спрятаны внутри функций.
Классы, вообще говоря, не предназначены для такого использования. |
Сообщ.
#10
,
|
|
|
А струкуры?
|
Сообщ.
#11
,
|
|
|
Ещё вариант.
#include <iostream> using namespace std; struct A { int a; }; struct B : public A { int b; }; struct C : public A { int c; }; int main() { B b; b.a = 2; b.b = 3; C c; c.a = 4; c.c = 5; std::cout << "1. B: {" << b.a << ", " << b.b << "}\n"; std::cout << "1. C: {" << c.a << ", " << c.c << "}\n"; b.A::operator =(c); std::cout << "2. B: {" << b.a << ", " << b.b << "}\n"; std::cout << "2. C: {" << c.a << ", " << c.c << "}\n"; return 0; } |
Сообщ.
#12
,
|
|
|
Предположу, что у автора семейство типов struct sockaddr. Не спорю, там такой бардак развели...
|
Сообщ.
#13
,
|
|
|
Цитата Qraizer @ Предположу, что у автора семейство типов struct sockaddr. Не спорю, там такой бардак развели... Ну, не совсем чтоб бардак - там что-то типа "распределённого union" Но в целом согласен, всякий раз, когда делаю все эти танцы вокруг sockaddr/sockaddr_in/sockaddr_in6, хочется вымыть руки |