class A
{
struct
{
unsigned short ID;
unsigned short Num;
// ....
} Package;
unsigned short &ID;
unsigned short &Num;
// ....
public:
A():ID(Package.ID),Num(Package.Num){};
};
Директивы препроцессора/макросы
Предположим есть класс
Код:
В нем ссылка инициализируется полем структуры, принадлежащей классу.
Хотелось бы написать макрос, который это счастье хотя бы так сворачивал (ну или во что-то похожее)
Код:
class A
{
__STRUCT_PACKAGE_BEGIN
__PACKAGE_FIELD_USHORT (ID);
__PACKAGE_FIELD_USHORT (Num);
__STRUCT_PACKAGE_END
public:
A():__PACKAGE_INIT(ID), __PACKAGE_INIT(Num){};
};
{
__STRUCT_PACKAGE_BEGIN
__PACKAGE_FIELD_USHORT (ID);
__PACKAGE_FIELD_USHORT (Num);
__STRUCT_PACKAGE_END
public:
A():__PACKAGE_INIT(ID), __PACKAGE_INIT(Num){};
};
Основная сложность на мой взгляд - продублировать поле внутри структуры, и в качестве ссылки за ее пределами. Есть у кого нибудь идеи как это реализовать?
Пытался смотреть
http://www.boost.org/doc/libs/1_46_1/libs/preprocessor/doc/index.html
но если честно, не вкурил, можно ли такое сделать с помощь этой библиотеки.
Тем более что подобное макросо-уродство явно не прибавит читабельности.
я все занимаюсь теоретическими изысками, как бы сделать класс удобным для передачи по сети.
так хочется сразу паковать готовую структуру и передавать ее на более низкий уровень. заодно запрещать поля, имеющие разную длину на разной разрядности.
в тоже время, хочется обращаться не через package.ID, а напрямую, как к обычному члену класса. для этого и ссылка на поле структуры.
т.е. по замыслу можно с ссылками работать, как с обычными переменными, не заморачиваясь их принадлежностью, и иметь возможность сделать Obj.get_package(), который вернет сразу структуру, готовую к обработке, без дополнительных телодвижений.
и таким образом работать со всеми классами, которые требуется передавать по сети.
как-то так.
Цитата: ~ArchimeD~
в тоже время, хочется обращаться не через package.ID, а напрямую, как к обычному члену класса.
А почему не сделать, например, что-то в стиле unnamed union? Как раз решит эту проблему.
Плюс не очень понятно чем собственно мешает обращение к полям структуры напрямую, если они действительно хранять протоколные данные. На мой взгляд в этом нет ничего плохого. А если ты когда нибудь решишь закрыть их методами - вобще не увидишь разницу.
Плюс, я так понимаю структуру ты хочешь непосредственно писать во вне программы (в сеть, файл еще куда - не важно)?
При этотм ты должен помнить о нескольких вещах:
Во первых это должна быть POD-структура без указателей. Ну с этим я думаю у тебя проблем нет - наверняка для этого ты поля и выносишь в структуру.
Во вторых ты должен быть уверен, что типы полей структуры на передающей и принимающей стороне имеют одинаковую длину и порядок байт. Хотя порядок байт каждого целого поля можно конечно перед отправкой приводить к сетевому. Хотя тут теряется удобство быстрой записи всей структуры.
Ну и в третьих ты должен быть уверен в отсутствии проблем с выравниванием структуры на передающей и принимающей стороне.
Если ты не можешь этого гарантировать - то возможно тебе стоит подумать просто о сериализации, а не заведении таких структур. То есть думать в сторону создания общего удобного тебе интерфейса для сериализации - не важно в сеть, файл, буфер в памяти?
Цитата: aks
Плюс не очень понятно чем собственно мешает обращение к полям структуры напрямую, если они действительно хранять протоколные данные. На мой взгляд в этом нет ничего плохого. А если ты когда нибудь решишь закрыть их методами - вобще не увидишь разницу.
Это да, но так придется для каждого класса прописывать индивидуально структуру и т.д. Раздумывая насчет макроса, я хотел унифицировать и сделать неявным добавление структуры в разных классах.
Цитата: aks
Плюс, я так понимаю структуру ты хочешь непосредственно писать во вне программы (в сеть, файл еще куда - не важно)?
При этотм ты должен помнить о нескольких вещах:
Во первых это должна быть POD-структура без указателей. Ну с этим я думаю у тебя проблем нет - наверняка для этого ты поля и выносишь в структуру.
Во вторых ты должен быть уверен, что типы полей структуры на передающей и принимающей стороне имеют одинаковую длину и порядок байт. Хотя порядок байт каждого целого поля можно конечно перед отправкой приводить к сетевому. Хотя тут теряется удобство быстрой записи всей структуры.
Ну и в третьих ты должен быть уверен в отсутствии проблем с выравниванием структуры на передающей и принимающей стороне.
1) это ессно. и вообще, планировал разрешить путем макросов только определенные типы данных в структуре.
2) насчет длины - п.1 (платформонезависимые по длине типы). а вот насчет порядка я лоханулся. т.е. про это я помнил, но забыл, что нужно на каждом поле такую операцию проводить. тогда да, смысл структуры теряется.
3) а вот про это вообще забыл :)
Цитата: aks
Если ты не можешь этого гарантировать - то возможно тебе стоит подумать просто о сериализации, а не заведении таких структур. То есть думать в сторону создания общего удобного тебе интерфейса для сериализации - не важно в сеть, файл, буфер в памяти?
ты имеешь ввиду создание некоего объекта? в который можно было бы покидать данные вроде
Код:
NetSender << ID << Num;
NetSender.send(sock);
NetSender.send(sock);
А затем на другой стороне получить
Код:
NetSender.recv(sock);
NetSender >> ID;
NetSender >> Num;
NetSender >> ID;
NetSender >> Num;
и который внутри себя бы уже проводил преобразование порядка байт и т.д.?
А насчет unnamed union не совсем понял мысль. Как к ней самой то обратиться, как к последовательности байт? :)
велосипеда не надумал :) Наверное, буде его использовать
Таки лучше
А что-то в духе protobuf или thrift не подходит? Скорее protobuf, конечно.