Одним из основных применений генерации кода в c ++ является поддержка сериализации сообщений.Как правило, вы хотите поддерживать указание содержимого и макета сообщения на одном шаге и создавать код для этого типа сообщения, который может дать вам объекты, которые можно сериализовать в / из потоков связи.В прошлом это обычно приводило к коду, который выглядит следующим образом:
class MyMessage : public SerialisableObject
{
// message members
int myNumber_;
std::string myString_;
std::vector<MyOtherSerialisableObject> aBunchOfThingsIWantToSerialise_;
public:
// ctor, dtor, accesors, mutators, then:
virtual void Serialise(SerialisationStream & stream)
{
stream & myNumber_;
stream & myString_;
stream & aBunchOfThingsIWantToSerialise_;
}
};
Проблема с использованием этого вида дизайна заключается в том, что он нарушает важное правило хорошей архитектуры: вам не нужно указывать намерениедизайн дважды.Дублирование намерений, как дублирование кода и другие обычные дубликаты разработки, оставляет место для одного места в коде, чтобы расходиться с другим, вызывая ошибки.
В приведенном выше примере дублирование - это список членов.Потенциальные ошибки включают в себя добавление члена в класс, но забывание добавить его в список сериализации, сериализацию члена дважды (возможно, не используя тот же порядок, что и объявление члена или, возможно, из-за неправильного написания аналогичного члена, среди других способов)или сериализацию чего-то, что не является членом (что может привести к ошибке компилятора, если поиск по имени не найдет что-то в другой области видимости, чем объект, соответствующий правилам поиска).Такая ошибка - та же самая причина, по которой мы больше не пытаемся сопоставить каждое выделение кучи с удалением (вместо этого используя интеллектуальные указатели) или когда-либо открывать файл с закрытием (используя механизмы RAII ctor // dtor) - мы не хотим иметьчтобы соответствовать нашим намерениям в нескольких местах, потому что бывают случаи, когда мы - или другой инженер, менее знакомый с намерением - совершаем ошибки.
В общем, поэтому это было одной из тех вещей, о которых может позаботиться генерация кода,Вы можете создать файл MyMessage.cg, чтобы указать макет и элементы за один шаг
serialisable MyMessage
{
int myNumber_;
std::string myString_;
std::vector<MyOtherSerialisableObject> aBunchOfThingsIWantToSerialise_;
};
, которые будут запускаться через утилиту генерации кода и генерировать код.
Мне было интересно,это было возможно сделать в C ++ 0x без генерации внешнего кода.Существуют ли какие-либо новые языковые механизмы, позволяющие определить класс как сериализуемый один раз, а имена и расположение его членов используются для компоновки сообщения во время сериализации?
Чтобы было ясно, я знаю, что естьтрюки с буст-кортежами и слиянием, которые могут приблизиться к такому поведению даже на языке до-++ 0x.Однако эти способы использования, основанные на индексации в кортеже, а не на доступе по имени-члену, были хрупкими для изменения компоновки, поскольку другие места в коде, которые получают доступ к сообщениям, также должны были бы быть переупорядочены.Необходим некоторый доступ по имени-члену, чтобы не дублировать спецификацию макета в местах кода, которые используют сообщения.
Кроме того, я знаю, что было бы неплохо перейти к следующемууровень и попросить указать, когда некоторые члены не должны быть сериализованными.Другие языки, которые предлагают встроенную сериализацию, часто предлагают для этого какой-то атрибут, поэтому int myNonSerialisedNumber_ [[noserialise]];может показаться естественным.Тем не менее, я лично считаю плохим проектирование иметь сериализуемые объекты, в которых все не сериализовано, поскольку время жизни сообщений находится в транспортном уровне к / от уровня связи, отдельно от других времен жизни данных.Кроме того, у вас может быть объект, который имеет чисто сериализуемый как один из его членов, так что такая функциональность ни в коем случае не предлагает язык.
Возможно ли это?Или комитет по стандартам упустил такую интроспективную возможность?Мне не нужно, чтобы это выглядело как файл кода gen выше - любой простой метод для определения компоновки и элементов компиляции во время компиляции за один шаг решит эту общую проблему.