В настоящее время я читаю исходный кодApache ThriftMsgstr «Более конкретно, код, который реализован на C ++, помещается в этот путь:» thrift-0.9.1.tar \ thrift-0.9.1 \ lib \ cpp «.
Мне было интересно, почему «класс TProtocol» разработан так:
Как мы знаем, TProtocol Class является абстрактным классом. И здесь есть подробный анализ:
«developermemo«И он говорит:« Также определяет соответствующий абстрактный фабричный класс для производства конкретного объекта протокола, который является наиболее часто используемым шаблоном проектирования ». «
Тем не менее, мне было интересно, почему они определяют функцию соответствующей чистой виртуальной функции называется. Например:
virtual uint32_t writeSetEnd_virt() = 0;
virtual uint32_t writeBool_virt(const bool value) = 0; //Pure virtual function
uint32_t writeBool(const bool value) { //
T_VIRTUAL_CALL();
return writeBool_virt(value); //call the "interface"}
Зачем нам нужно «writeBool ()». Кажется, это бесполезно.
Почему бы нам просто не определить «чисто виртуальные функции» и «производные классы», переписать эти интерфейсы.
Этот шаблон называется «метод шаблона». У вас часто бывает такая комбинация публичной, не виртуальной функции и частной виртуальной функции. Помимо пересылки, общедоступный выполняет такие вещи, как проверка предварительных условий и постусловий, ведение журнала и простые преобразования. Частный, виртуальный делает реальную работу. Основанием для того, чтобы сделать его закрытым, является прояснение того, что у вас нет выбора для вызова базовой версии, что вы можете сделать в противном случае с явным derived.base::foo()
вызов. Если вам нужно расширить базовую версию, вы также можете сделать ее защищенной, но здесь это не так.
Как можно заметить… writeBool
делает больше, чем просто звонок writeBool_virt
, Это также исполняет T_VIRTUAL_CALL();
, который отслеживает выполнение в отладочных сборках.
Невозможно создать такое поведение только с помощью виртуальных функций, поскольку вы не можете гарантировать, что каждый производный класс будет правильно вызывать T_VIRTUAL_CALL();
,
Виртуальные вызовы выполняют минимально возможную работу (они просто дают точку для настройки поведения TProtocol
) и не являются частью внешнего публичного интерфейса. Это уменьшает связь между компонентами и делает реализацию TProtocol
быть более приватным.