2009-12-12 38 views
1

我只是阅读迈尔斯“更有效的C++ 35新方法” - 第33项,他建议 总是要从抽象基类继承而不是具体的。抽象类和多态使用数组

他声称,我不能完全理解的原因之一是,从一个抽象类继承,多态处理数组(本书中的第3项)不是问题。

有人可以建议这是怎么回事?

此外,我想听听是否永远不会让客户端实例化其他派生类的好东西? (在他的书中迈尔斯是示出具有例如赋值运算符中的问题)的要求

代码例如:

CLASS BST {....};

CLASS BlanacedBST ::公共BST {....}

空隙printBSTArray(ostream的& S,const的BST阵列[],INT包含numElements) { 对(INT I = 0;我<包含numElements; i ++) { s < < array [i]; } }

BST BSTArray [10]; printBSTArray(BSTArray); //正常工作

BlanacedBST bBSTArray [10]; printBSTArray(bBSTArray); //未定义的行为(因为下标操作符根据BST块大小推进指针)

然后,他加入了避免从另一个concreat class(BST)继承的concreate class(BlanacedBST)通常避免了这个问题 - 不管怎样。

+0

当有人建议做任何事情*永远*或*永远*你可以放心地忽略其余。 – 2009-12-12 15:31:02

+0

是的,它总是*安全地忽略其余;-) – 2009-12-12 15:31:45

+0

我没有这本书,所以我不能解决你在这方面的具体问题,虽然我熟悉他的建议只有纯粹抽象基类。也许你可以粘贴他使用的代码示例? – Omnifarious 2009-12-12 17:48:41

回答

2

虽然我认为避免从非抽象类继承是一个很好的设计指南,应该让你对你的设计思考三次,但我绝对不认为它属于“从不这样做”的范畴。

我会说由于切片问题,设计为从其中继承数据的类应该隐藏它们的赋值运算符。

我认为有一种方法可以对不经常想到的类进行分类,我认为这会导致很多混淆。我认为有些类被设计为被值使用,而类被设计为总是被引用使用(意味着通过引用或指针或类似的东西)。

在大多数面向对象的语言中,用户定义的类只能被引用使用,并且有一个特殊的类可以被值使用。 C++的一大优势是你可以创建可以按值使用的用户定义类。这可能会带来一些巨大的效益。例如,在Java中,您的所有观点(挑选一个随机简单的类)都是堆分配的,并且需要进行垃圾回收,尽管它们基本上只有两三个双打,还有一些不错的“最终”支持功能。

因此,被设计为供引用使用的类应禁用分配,并应认真考虑禁用复制构造,并要求人们为此使用“为此虚拟功能制作副本”。请注意,Java类通常没有像赋值运算符或标准拷贝构造函数那样的东西。

设计为由值使用的类应该通常不具有虚函数,尽管将它们作为继承层次结构的一部分可能非常有用。它们仍然可能相当复杂,但是因为它们可以包含对引用使用的类对象的引用。

如果您需要将引用类作为值来使用,则应使用句柄/主体设计模式或智能指针。 STL容器都是设计用于值对象,所以这是一个相当普遍的问题。

1

迈尔斯并没有说你可以创建没有问题的数组;他说,你尝试创造它会更困难。当你尝试初始化它时,编译器就会抱怨,因为如果它是抽象的,你就不能创建基类的对象。

+0

但事情并不是试图创建基础调用,而是使用基础调用作为函数参数,并将派生类作为参数发送......所以我仍然无法看到如何使用抽象帮助 – Idan 2009-12-12 16:37:35

+0

但是,可以填充指向基类的指针数组。 – 2009-12-12 21:37:51