“向上倾斜”的缺点是什么?

时间:2011-11-08 07:20:03

标签: c++ virtual abstract-class upcasting

抽象类的目的不是让开发人员创建基类的对象,然后 upcast 它,AFAIK。

现在,即使不需要向上转播,我仍然使用它,它是否会以某种方式证明“不利”

更多澄清:
来自C ++中的思考:

  

通常在设计中,您希望基类只显示一个   其派生类的接口。也就是说,你不希望任何人   实际上创建了一个基类的对象,只是为了向上转换它   它的界面可以使用。这是通过制作该课程来实现的   摘要,

通过向上转发,我的意思是:baseClass *obj = new derived ();

4 个答案:

答案 0 :(得分:4)

对于非多态类,上传可能是不利的。例如:

class Fruit { ... };  // doesn't contain any virtual method
class Apple : public Fruit { ... };
class Blackberry : public Fruit { ... };

在某个地方向上翻,

Fruit *p = new Apple;  // oops, information gone

现在,如果*pAppleBlackberry的实例,您永远不会知道(没有任何手动机制)。

[请注意,非多态类不允许使用dynamic_cast<>。]

答案 1 :(得分:2)

抽象类用于表示一组(子)类共有的概念,但创建实例是不明智的。

考虑一个班级Animal。创建该类的实例是没有意义的,因为没有东西只是一种动物。有鸭子,狗和大象,每个都是动物的子类。通过正式宣布类动物,你可以捕捉到所有类型动物的相似性,并通过使它成为抽象,你可以表达它无法实例化。

在静态类型语言中使用多态性需要向上转换。正如@Jigar Joshi在评论中指出的那样,这就叫Liskov Substituion Principle

编辑:向上转换不是不利的。实际上,您应该尽可能地使用它,使您的代码依赖于超类(接口)而不是基类(实现)。这使您可以在以后切换实现而无需更改代码。

答案 2 :(得分:0)

一个缺点是派生类中引入的新功能明显丢失:

class A
{
   void foo();
}

class B : public A
{
   void foo2();
}

A* b = new B;
b->foo2(); //error - no longer visible

我在这里谈论非虚拟功能。

此外,如果您忘记将析构函数设置为虚拟,则在通过指向基础对象的指针删除派生对象时可能会出现内存泄漏。

然而,所有这些都可以通过良好的架构来避免。

答案 3 :(得分:0)

向上转换是一种技术工具。

与所有工具一样,正确使用时非常有用,如果使用不一致则危险/不利。

取决于您希望代码在给定编程范例方面的“纯粹”程度,这可能是好的还是坏的。

现在,C ++不一定是“纯粹的OOP”,不一定是“纯粹的通用”,不一定是“纯粹的功能”。而且由于C ++是一种“实用的语言”,它通常不是一种优势,它迫使它适应“唯一的范式”。

在技术方面,唯一可以说的是,

  • 派生类是基类加上更多
  • 引用通过基指针派生的内容会使“更多内容”无法访问,除非基础中有一种机制可以让您跳转到派生范围。
  • C ++提供的机制隐式跳转是虚函数。
  • C ++提供的显式跳转的机制是dynamic_cast(用于向下转换)。
  • 对于非多态对象(没有任何虚方法),static_cast(向下转发)仍然可用,但没有运行时检查。

优点和缺点源于所有这些点的一致和不一致的使用。这不仅仅与垂头丧气有关。