C++标准库的容器类层次结构

3

我一直在想,C++语言在std标准库中为什么没有使用纯虚抽象类来设计任何容器?

我很欣赏hash_map后来从stdext名称空间中引入,但它与std标准库中的接口非常相似。如果我决定稍后想要为特定软件实现自己的映射表,我希望有某种接口可以使用。

例子

std::base_map *foo = new std::map<std::string, std::string>;
delete foo;
foo = new stdext::hash_map<std::string, std::string>;

显然,就我所知,上述示例是不可能的。但是对于列表和其他标准库容器来说也是类似的。

我知道这不是C#或Java,但在C++中显然没有限制阻止这种设计,那么为什么要这样设计,以便在类似容器之间没有耦合呢?

1个回答

2
因为虚函数会增加开销。
由于容器的接口不完全相同,尽管有一些共同的函数,但在迭代器失效和内存分配(因此也包括异常行为)方面存在重要的差异,需要了解这些差异。如果您使用抽象基类,则无法知道具体容器的行为方式。
如果您想编写与传递的容器类型无关的代码,则在C++中,您应该编写一个模板而不是依赖于抽象接口,即使用静态多态而不是动态多态。这样可以避免动态分派的开销,并允许基于具体类型进行专门化,因为具体类型在编译时已知。
最后,我认为这样做没有任何优势。现在的方式更好。正如您所说,这不是C#或Java,谢天谢地。
(附言:stdext命名空间不属于C++,它似乎是Microsoft的非标准类型命名空间,更好的例子应该使用std :: tr1 :: unordered_map或std :: unordered_map而不是stdext :: hash_map)。

这解决了我的疑惑,我之前忽略了虚函数开销,并且我理解了您关于使用静态多态性的说法。我知道并非所有容器都具有相同的接口,但我认为共享功能应该有自己的接口。您总是可以向下转换回子类型,但我也明白除非绝对必要,否则应该避免向下转换。感谢您的答案! :-) - chrisw
2
C++的RTTI非常有限,你不能使用反射或其他方式来查找具体类型,因此除非你已经知道具体类型,否则无法进行向下转型。如果你已经知道具体类型,那么为什么还要使用多态性呢? - Jonathan Wakely

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接