好处 1:命名空间方面
确实,A 为B 提供了一个命名空间,这可以帮助我们更好地构建我们的代码。考虑一个具体的例子,vector 代表A,iterator 代表B。可以说,
class vector {
public:
class iterator { /*...*/ };
iterator begin() { /*...*/ }
};
比输入、阅读和理解更容易
class vector_iterator {
/*...*/
};
class vector {
public:
vector_iterator begin() { /*...*/ }
};
特别注意:
1234563相互类型依赖可能导致无法解决的情况。 (使用嵌套类更容易避免此类问题,因为在嵌套类定义的大部分部分中,外部类被认为是完全定义。这是由于 §9.2/2。)
您很可能有许多其他数据类型维护自己的iterator,例如linked_list。使用上面的第二个版本,您需要将linked_list_iterator 定义为一个单独的类。您添加的这些“依赖”类型和替代类型越多,类名称就会变得越长越复杂。
好处 2:模板
继续上面的例子,现在考虑一个函数模板,它接受一个容器(例如上面定义的vector 和linked_list)作为参数并迭代它们:
template <typename Container>
void iterate(const Container &container) {
/*...*/
}
在这个函数中,您显然非常喜欢使用Container 的迭代器类型。如果那是嵌套类型,那就简单了:
typename Container::iterator
但如果不是,则必须将迭代器类型作为单独的模板参数:
template <typename Container, typename Iterator>
void iterate(const Container &container) {
/*...*/
Iterator it = container.begin();
/*...*/
}
如果该迭代器类型没有出现在函数参数中,编译器甚至无法猜测类型。每次调用 iterate 函数时,都必须将其显式添加到尖括号中。
最后说明:这些都与嵌套类是声明为公共还是私有无关。我上面的例子表明了公共嵌套类型显然更可取的情况,因为我认为iterator 类型应该能够在容器类之外使用。