我正在阅读std::sub_match<BidirectionalIterator>
的文档,并看到它公开继承自std::pair<BidirectionalIterator, BidirectionalIterator>
。由于sub_match
只是一对字符序列中的迭代器,带有一些附加函数,我可以理解它是用pair
实现的,但为什么要使用公共继承?
从std::pair<T,U>
公开继承的问题与从大多数其他标准类公开继承的问题相同:它们并不意味着以多态方式进行操作(特别是它们没有定义虚拟析构函数)。其他成员也将无法正常工作,即赋值运算符和交换成员函数(它们不会复制matched
的{{1}}成员。)
为什么Boost开发人员和委员会决定通过公开继承sub_match
而不是使用组合来实现sub_match
(如果他们想通过{{1保持成员访问权限,则使用声明的私有继承) }和pair
)?
答案 0 :(得分:5)
这是一个有趣的问题。据推测,他们认为这是安全的
因为没有人会动态分配一个。有关
只有你获得sub_match
个对象的方式才是返回值
来自basic_regex
的一些功能,或作为其他功能的副本
sub_match
,所有这些都是临时或本地的
变量。
请注意,无论如何都要保留sub_match
个对象是不安全的
它们包含迭代器,其生命周期......似乎没有在中指定
标准。在重用match_results
对象之前?直到
填充string
的函数的match_results
操作数
物体被破坏了?或?
我仍然避免了公共遗产。但在这种情况下,它是
不像它看起来那么危险,因为你真的没有理由
想要动态分配sub_match
。
答案 1 :(得分:3)
以下是regex
作者对此所说的内容:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1429.htm#matches_discussion
我担心你的问题没什么特别的。
我猜这个决定是重新发明轮子和引入一点误用风险之间的权衡。请注意,通常不需要构造sub_match
,它们是从regex
函数返回的。此外,成对的迭代器是实现范围的一种非常实用的方法。
答案 2 :(得分:3)
因为C ++没有办法继承没有公共继承的接口。您可以继承具有私有继承的实现,但随后一切都是私有的。如果您想要与std::pair
相同的界面,则必须 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%安全的。几乎没有理由在堆上分配它们并通过指针使用它们。因此,虽然我理解您的担忧,但我认为它不太可能发生在任何真正的代码中。
答案 3 :(得分:0)
因为他们不需要虚拟析构函数? ; - )
答案 4 :(得分:0)
如果std::sub_match<BidirectionalIterator>
没有自己的状态,那么它可以从std::pair
继承。不要在家里做。