Почему std:: sub match публично наследуется от std:: pair?
Я читал документацию std::sub_match<BidirectionalIterator>
и увидел, что он публично наследует от std::pair<BidirectionalIterator, BidirectionalIterator>
. Сsub_match
- это просто пара итераторов в последовательности символов, с некоторыми дополнительными функциями, я могу понять, что он реализован с помощью pair
, но зачем использовать открытое наследование?
проблема с наследованием публично от std::pair<T,U>
это то же самое, что и наследование публично от большинства других стандартных классов: они не предназначены для полиморфного манипулирования (в частности, они не определяют виртуальный деструктор). Другие члены также не будут работать должным образом, а именно оператор присваивания и функция-член swap (они не будут копировать matched
член sub_match
).
Почему разработчики Boost, а затем комитет решил реализовать sub_match
публично наследовать от pair
вместо использования композиции (или частного наследования с использованием деклараций, если они хотели сохранить доступ к членам через first
и second
)?
5 ответов
это интересный вопрос. Предположительно, они считали это безопасным
потому что никто никогда не будет динамически распределять их в любом случае. Об
единственный способ получить sub_match
objects является возвращаемым значением
из некоторых функций basic_regex
, или копии иных
sub_match
, и все они будут либо временными, либо локальными
переменная.
обратите внимание, что это не безопасно держать sub_match
объекты вокруг в любом случае, так как
они содержат итераторы, срок службы которых... не кажется указано в
стандарт. Пока
потому что C++ не может наследовать интерфейс без публичного наследования. Вы можете наследовать реализацию с частным наследованием, но тогда все является частным. Если вы хотите тот же интерфейс, что и std::pair
вы должны быть a std::pair
.
кроме того, рассмотрим это. Это, очевидно, неопределенное поведение:
std::sub_match<BidirectionalIterator> theMatch = ...;
std::pair<BidirectionalIterator> *pMatch = &theMatch;
delete pMatch;
но вот это:
std::sub_match<BidirectionalIterator> theMatch = ...;
std::pair<BidirectionalIterator> *pMatch = &theMatch.pair;
delete pMatch;
почему первый из них гораздо больше беспокоит, чем второй?
sub_match
и pair
являются легкими объектами (в зависимости от их содержания, конечно). Они предназначены для копирования или передачи по ссылке, все из которых на 100% безопасны. Существует мало, если есть какая-либо причина, чтобы выделить их в куче и использовать их через указатели. Поэтому, хотя я понимаю вашу озабоченность, я думаю, что это вряд ли произойдет в любом реальном коде.
вот что regex
автор должен сказать об этом: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1429.htm#matches_discussion
боюсь, ничего особенного в вашем вопросе.
Я бы предположил, что это решение было компромиссом между изобретением колеса и введением небольшого риска неправильного использования. Обратите внимание, что в общем случае нет необходимости создавать sub_match
они возвращались из . Сверх того пары итераторы - очень практичный способ реализации диапазонов.
Если std::sub_match<BidirectionalIterator>
не имеет собственного состояния, тогда это нормально для него наследовать от std::pair
. Только не дома.