通过继承扩展C ++标准库? [英] Extending the C++ Standard Library by inheritance?
问题描述
这是一个普遍认为的C ++标准库通常不打算使用继承扩展。当然,我(和其他人)批评那些建议从类如 std :: vector
派生的人。不过,这个问题: c ++异常,可以what()是NULL?我意识到,至少有一部分标准库的意图是这样扩展 - std :: exception
。
It is a commonly held belief that the the C++ Standard library is not generally intended to be extended using inheritance. Certainly, I (and others) have criticised people who suggest deriving from classes such as std::vector
. However, this question: c++ exceptions, can what() be NULL? made me realise that there is at least one part of the Standard Library that is intended to be so extended - std::exception
.
所以,我的问题有两部分:
So, my question has two parts:
-
是否有任何其他标准库类从
Are there any other Standard Library classes which are intended to be derived from?
如果从标准库类派生,如 std :: exception
一个由ISO标准中描述的接口绑定?例如,使用 what()
成员函数的异常类的程序不返回NTBS(假设它返回一个空指针)是否符合标准?
If one does derive from a Standard Library class such as std::exception
, is one bound by the interface described in the ISO Standard? For example, would a program which used an exception class who's what()
member function did not return a NTBS (say it returned a null pointer) be standard conforming?
推荐答案
我真的希望标准对于预期的使用是什么更清楚一点。也许应该有一个C ++原理文档与语言标准一起。在任何情况下,这里是我使用的方法:
Good nice question. I really wish that the Standard was a little more explicit about what the intended usage is. Maybe there should be a C++ Rationale document that sits alongside the language standard. In any case, here is the approach that I use:
(a)我不知道任何这样的列表的存在。相反,我使用以下列表来确定标准库类型是否可能被设计为继承自:
(a) I'm not aware of the existence of any such list. Instead, I use the following list to determine whether a Standard Library type is likely to be designed to be inherited from:
- t有任何
virtual
方法,那么你不应该使用它作为基础。这排除了std :: vector
等。 - 如果它有
virtual
方法,那么它是用作基类的候选。 - 如果有很多
friend
- 如果它是一个模板,那么在继承它之前要仔细一些,因为你可以使用专门化来定制它。
- 存在基于策略的机制(例如,
std :: char_traits
)是一个很好的线索,你不应该使用它a base。
- If it doesn't have any
virtual
methods, then you shouldn't be using it as a base. This rules outstd::vector
and the like. - If it does have
virtual
methods, then it is a candidate for usage as a base class. - If there are lots of
friend
statements floating around, then steer clear since there is probably an encapsulation problem. - If it is a template, then look closer before you inherit from it since you can probably customize it with specializations instead.
- The presence of policy-based mechanism (e.g.,
std::char_traits
) is a pretty good clue that you shouldn't be using it as a base.
不幸的是,我不知道一个不错的全面或黑白名单。
Unfortunately I don't know of a nice comprehensive or black and white list. I usually go by gut feel.
(b)我会使用 LSP 。如果有人在你的异常上调用 what()
,那么它的observable行为应该匹配 std :: exception
。我不认为这是一个标准一致性问题,而是一个正确性问题。该标准不要求子类可替代基类。这只是一个最佳实践。
(b) I would apply LSP here. If someone calls what()
on your exception, then it's observable behavior should match that of std::exception
. I don't think that it is really a standards conformance issue as much as a correctness issue. The Standard doesn't require that subclasses are substitutable for base classes. It is really just a "best practice".
这篇关于通过继承扩展C ++标准库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!