可能重复:
使用嵌套 C++ 类和枚举的优缺点?
考虑以下声明。
class A {
public:
class B{
};
};
没什么特别的。
- 但是这样做有什么好处呢?
- 将一个类放在另一个类中可能有什么原因?
- 两个类之间没有继承优势。
- 如果将 B 放在 A 内部是为了共享其私有名称,那么 A 对于 B 来说只是一个命名空间,并且有理由将 B 设为私有。
你怎么看待这件事?
可能重复:
使用嵌套 C++ 类和枚举的优缺点?
考虑以下声明。
class A {
public:
class B{
};
};
没什么特别的。
你怎么看待这件事?
从概念上讲,它让程序员知道 B 类与 A 类特别相关。当您在 A 类之外使用 B 类时,您必须使用 A::B 类型,这每次都会提醒您 B 是与 A 相关。这不会添加任何功能,但显示了关系。
同样,您根本不必使用继承/组合或类。您可以或多或少地通过使用结构和函数来模拟 C 中的类。这只是一种让代码更简洁、更直接的方法,让程序员更容易将代码与设计联系起来。类比公共子类更能做到这一点,但这只是一个例子。
如果它是一个私有/受保护的子类(我认为它不在您的示例中),那么这显然将该类限制为该类和该类的子类的实现,如果唯一的该类的用例在该类(可能还有它的子类)的实现中。
好处 1:命名空间方面
事实上,A
为 提供了一个命名空间B
,这可以帮助我们更好地构建我们的代码。考虑一个带有vector
forA
和iterator
for的具体示例B
。可以说,
class vector {
public:
class iterator { /*...*/ };
iterator begin() { /*...*/ }
};
比打字、阅读和理解更容易
class vector_iterator {
/*...*/
};
class vector {
public:
vector_iterator begin() { /*...*/ }
};
特别注意:
当两个类 (vector
和iterator
) 相互依赖时,即使用彼此的成员,上面的第二个版本将需要前向声明这两个类中的一个,并且在某些情况下,相互的类型依赖可能会导致无法解决的情况。(使用嵌套类,避免此类问题要容易得多,因为在嵌套类定义的大部分部分中,外部类被认为是完全定义的。这是由于 §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
类型应该能够在容器类之外使用。