Чтобы учесть специфику иерархической обработки для унификации и систематизации символьных строк в программе uni, целесообразно сформировать класс StrNode, производный от базового класса бинарных деревьев BiNode. Объекты класса StrNode должны описывать иерархию бинарного дерева, узлы которого предназначены для хранения текстовых строк. Производный класс StrNode должен наследовать компоненты базового класса и содержать собственные частные (private) компоненты-данные и общедоступные (public) компонентные методы, учитывающие особенности иерархической обработки символьных строк. В соответствии с правилами реализации принципа наследования в системе программирования С++, декларацию класса StrNode можно специфицировать следующим образом:

  class StrNode : public BiNode 
  { 
  private : /*спецификация собственных компонент-данных*/ 
  public  : /*спецификация собственных компонентных методов*/ 
  }; 

Категория наследования public выбрана для того, чтобы сохранить в производном классе привилегии доступа к компонентам, установленные в базовом классе.
В спецификацию собственных частных компонент производного класса StrNode следует включить объявление информационного поля str типа (char*) для хранения адресов строк текстовых данных. Содержание поля str одновременно используется для идентификации узла по ключу в алгоритме поиска по бинарному дереву, выращенному из производных объектов класса StrNodE, а также для выполнения информационной обработки при обходе узлов бинарного дерева.
Символьный тип информационных данных определяет особенности узлов бинарного дерева производных объектов в классе StrNode и, соответственно, специфику их обработки.
Для инициализации текстовых данных при создании нового узла в классе StrNode рекомендуется предусмотреть конструктор с аргументом типа (char*), через который должно передаваться требуемое содержание поля str. Необходимый объем памяти для хранения переданных данных должен динамически выделяться из кучи с помощью оператора new системы программирования C++. Для оценки размера переданных данных и копирования их по адресу str рекомендуется использовать библиотечные функции strlen и strcpy, которые наиболее часто применяются для обработки символьных строк в системе программирования С. Для инициализации наследованных адресных полей базового класса BiNode, конструктор производного класса StrNode должен предусматривать вызов конструктора базового класса без аргументов BiNode(). Вызов конструктора базового класса следует обозначить в списке инициализаций конструктора производного класса, оформив заголовок его спецификации следующим образом:

StrNode :: StrNode (char*s) : BiNode() {......}

Для очистки памяти, динамически распределенной конструктором, в классе StrNode следует предусмотреть деструктор ~StrNode(), который будет автоматически вызываться при удалении объектов данного класса. Для освобождения памяти, динамически распределенной по адресу str, деструктор класса StrNode должен использовать оператор delete системы программирования С++. Рекомендуется предусмотреть индикацию вызова деструктора, отображая соответствующее информационное сообщение в потоке стандартной диагностики stderr. Для форматного вывода диагностических сообщений следует использовать библиотечные функции fputs и fprintf потокового ввода-вывода системы программирования С и С++.
В общедоступную часть объявления производного класса StrNode необходимо включить декларацию компонентных методов, которые реализуют виртуальные интерфейсы базового класса BiNode (identify и insert) при поиске по ключу и обеспечивают требуемую функциональную обработку при прохождении узлов бинарного дерева (print и destroy). Кроме них в общедоступной части класса StrNode целесообразно дополнительно декларировать 2 компонентных метода: search и duplicate. Один - для перегрузки наследованного базового компонентного метода search, который реализует универсальный поиск по бинарному дереву. Второй - для индикации результатов поиска. Все перечисленные компонентные методы производного класса StrNode имеют короткий код и могут быть специфицированы как inline-подстановки непосредственно в объявлении класса StrNode.
Компонентный метод identify перегружает соответствующую чистую виртуальную функцию базового класса BiNode, реализуя специфичный для производного класса StrNode способ сравнения ключей при поиске по бинарному дереву. Учитывая символьный тип информационного поля в классе StrNode, рекомендуется применить для сравнения ключей библиотечную функцию strcmp системы программирования С и С++. Аргументами функции strcmp в компонентном методе identify должны быть адрес переданного ключа и адрес из информационного поля текущего узла (str), соответственно. Чтобы соблюсти соответствие типов данных, адрес ключа поиска, переданный как указатель типа (void*), следует явно преобразовать к типу (char*) при подстановке в функцию strcmp. Код возврата функции strcmp рассматривается как код возврата компонентного метода identify и используется как указано в базовом методе search. Компонентный метод insert перегружает соответствующую чистую виртуальную функцию базового класса BiNode для того, чтобы обеспечить создание нового узла бинарного дерева как объекта производного класса StrNode, когда это необходимо в базовом компонентном методе search. Создание нового узла осуществляет конструктор класса StrNode, вызов которого в методе insert должен инициировать оператор new системы программирования С++. Полученный через аргумент адрес необнаруженного ключа поиска (типа void*) следует передавать конструктору производного класса в операторе new после явного преобразования к типу (char*). Явное преобразование типа необходимо, поскольку в производном классе StrNode не определен никакой другой конструктор, кроме StrNode (char*). При успешном завершении в данном контексте оператор new возвратит адрес нового узла бинарного дерева в производном классе StrNode. Этот адрес следует рассматривать как возврат компонентного метода insert. Следующий фрагмент С++ кода можно рассматривать как рекомендуемый вариант спецификации компонентного метода insert:

  class StrNode : public BiNode 
  { 
  ................................ 
  BiNode * insert (void * s) 
  { 
   return (new StrNode ((char*) s)); 
  }
  ................................ 
  }; 

Возврат оператора new в данном контексте будет иметь тип (StrNode*), который автоматически приводится к типу (BiNode*) как требует спецификация метода insert в базовом и производном классе. Указанное преобразование типа является корректным, т. к. система программирования С++ допускает присвоение адреса объекта производного класса по адресу базового класса и выполняет его автоматически, т. е. (StrNode*) может быть использован там, где ожидается (BiNode*). Полученный адрес нового узла в классе StrNode используется соответствующим образом в наследованном от базового класса методе search, как того требует алгоритм поиска по бинарному дереву.
Следует отметить, что неявное преобразование типа при присваивании адреса объекта базового класса указателю на производный класс не считается корректным в системе программирования С++. Поэтому код возврата базового компонентного метода search, имеющий тип (BiNode*),нельзя непосредственно присвоить переменной типа указателя на производный класс (StrNode*), например, в основной функции main программы uni. Для согласования типов указателей в данном случае рекомендуется перегрузка базового метода search в производном классе StrNode, которая может быть специфицирована, например, следующим образом:

  class StrNode : public BiNode 
  { 
  ............................. 
  StrNode*search (void*s) 
  { 
   return ((StrNode*) BiNode::search (s)); 
  }; 
  .............................. 
  }; 

Актуальность перегрузки базового компонентного метода search в производном классе StrNode объясняется необходимостью использовать код возврата этого метода для возврата для отображения результатов поиска компонентным методом duplicate, который должен вызываться через объект или указатель на объект производного класса StrNode. Этот метод не должен возвращать значение или иметь аргументы. Он должен отображать в поток стандартной диагностики (stderr) предупреждение, о том, что при поиске по бинарному дереву обнаружен дубликат ключа. Для отображения предупреждения компонентный метод duplicate может использовать библиотечную функцию fprintf или fputs системы программирования С и С++. При нулевом (NULL) возврате компонентного метода search, когда дубликат ключа не обнаружен, метод dublicate вызываться не должен.
Функциональная обработка узлов при прохождении узлов бинарного дерева в производном классе StrNode должна предусматривать отображение информационного поля str каждого узла и уничтожение узлов. Для выполнения указанной обработки рекомендуется предусмотреть в классе StrNode компонентные методы print и destroy, соответственно. Эти компонентные методы не должны иметь аргументы и код возврата. Их адреса предназначены для передачи в базовые методы прохождения бинарного дерева (preorder, intorder и postorder), и их код очень прост. В частности, компонентный метод print должен только вызвать библиотечную функцию puts системы программирования С и С++ для отображения символьной строки str информационного поля текущего узла бинарного дерева в классе StrNode через поток стандартного вывода (stdout). Предполагая динамическое распределение памяти для хранения узлов бинарного дерева в классе StrNode, компонентный метод destroy должен только использовать оператор delete, чтобы инициировать деструктор класса. Например, спецификация компонентного метода destroy в классе StrNode может иметь следующий формат:

 class StrNode : public BiNode 
  { 
  ......................... 
  void destroy() { delete this; return; }; 
  ......................... 
  }; 

Компонентные методы print и destroy могут быть вызваны обычным образом через объекты, ссылки или адреса объектов класса StrNode для индивидуальной обработки узлов бинарного дерева. Кроме того, выбор прототипов этих методов позволяет передавать их адреса наследованным методам preorder, inorder и postorder для выполнения систематической функциональной обработки узлов при прохождении бинарного дерева в прямом, симметричном и концевом порядке, соответственно. Для того, чтобы обеспечить корректность передачи достаточно выполнить явное преобразование их адресов к типу VISIT, декларированному для аргументов базовых методов прохождения бинарных деревьев. Формат преобразования типа демонстрирует следующий пример обращения к наследованному базовому методу inorder для отображения информационных полей узлов бинарного дерева из объектов класса StrNode в симметричном порядке, начиная с корня (root):

root -> inorder ((VISIT) & StrNode :: print );

Указанное преобразование типа необходимо, потому что специфицированные в базовом классе компонентные методы прохождения бинарного дерева ожидают получить через аргумент указатель на компонентный метод базового класса BiNode, а не указатель на компонентный метод производного класса StrNode. Аналогичный формат следует использовать для обращения, например, к наследованному компонентному методу postorder при прохождении бинарного дерева в концевом порядке с целью очистки памяти его узлов компонентным методом destroy производного класса StrNode. В обоих случаях реализуется механизм косвенной адресации компонентных методов, который позволяет обращаться к компонентам через их адреса в структуре класса.
Перечисленные компонентные методы производного класса StrNode могут быть использованы в основной функции main программы uni по 2-х этапной схеме обработки бинарных деревьев, где этап поиска обеспечивает компонентный метод search (в сочетании с компонентным методом duplicate для индикации обнаруженных дубликатов), а этап прохождения реализуют компонентные методы inorder и postorder, которым передаются адреса компонентных методов print и destroy, чтобы осуществить требуемую функциональную обработку узлов.
Обращение к компонентным методам производного класса StrNode в основной функции main следует осуществлять через указатель на объекты производного класса (StrNode*). Для доступа к динамически распределенным узлам бинарного дерева из объектов производного класса, следует хранить адрес корня, зарезервировав для этой цели отдельную автоматическую переменную (например root) в функции main, типа (StrNode*).