为什么std :: sub_match <t>公开继承自std :: pair <t,t =“”>?</t,> </t>

时间:2011-10-27 14:56:36

标签: c++ regex boost c++11

我正在阅读std::sub_match<BidirectionalIterator>的文档,并看到它公开继承自std::pair<BidirectionalIterator, BidirectionalIterator>。由于sub_match只是一对字符序列中的迭代器,带有一些附加函数,我可以理解它是用pair实现的,但为什么要使用公共继承?

std::pair<T,U>公开继承的问题与从大多数其他标准类公开继承的问题相同:它们并不意味着以多态方式进行操作(特别是它们没有定义虚拟析构函数)。其他成员也将无法正常工作,即赋值运算符和交换成员函数(它们不会复制matched的{​​{1}}成员。)

为什么Boost开发人员和委员会决定通过公开继承sub_match而不是使用组合来实现sub_match(如果他们想通过{{1保持成员访问权限,则使用声明的私有继承) }和pair)?

5 个答案:

答案 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_matchpair是轻量级对象(当然取决于它们的内容)。它们旨在通过引用复制或传递,所有这些都是100%安全的。几乎没有理由在堆上分配它们并通过指针使用它们。因此,虽然我理解您的担忧,但我认为它不太可能发生在任何真正的代码中。

答案 3 :(得分:0)

因为他们不需要虚拟析构函数? ; - )

答案 4 :(得分:0)

如果std::sub_match<BidirectionalIterator>没有自己的状态,那么它可以从std::pair继承。不要在家里做。