"upcasting"的缺点是什么?

What are the disadvantages of "upcasting"?

本文关键字:是什么 upcasting 缺点      更新时间:2023-10-16

抽象类的目的不是让开发人员创建基类的对象,然后向上转换

现在,即使不需要向上转换,我仍然使用它,它是否在某种程度上证明是"不利的" ?

更多的澄清:

通常在设计中,您希望基类只显示一个接口,用于其派生类。也就是说,你不想让任何人知道实际上创建一个基类的对象,只是为了向上转换到它,以便它的接口可以使用。这是通过创建这个类来完成的抽象的,

我指的是:baseClass *obj = new derived ();

对于非多态类来说,向上转换可能是不利的。例如:

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<>不允许非多态性类]

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

考虑一个类Animal。创建这个类的实例是没有意义的,因为不存在仅仅是动物的东西。有鸭子、狗和大象,它们都是动物的一个亚纲。通过正式声明类animal,您可以捕获所有类型动物的相似之处,并且通过使其抽象,您可以表示它不能被实例化。

在静态类型语言中,要使用多态性需要进行上转换。正如@Jigar Joshi在评论中指出的那样,这被称为Liskov替代原理。

Edit:升级不是不利的。事实上,您应该尽可能使用它,使您的代码依赖于超类(接口)而不是基类(实现)。这使您以后可以在不更改代码的情况下切换实现。

升级是一种技术工具。

就像所有的工具一样,如果使用正确,它是有用的,如果使用不一致,它是危险的。

它可以是好或坏,这取决于你希望你的代码在给定的编程范例中有多"纯粹"。

现在,c++不一定是"纯面向对象",不一定是"纯泛型",不一定是"纯函数"。而且,由于c++是一种"实用语言",一般来说,强迫它适应"唯一的范式"并不是一种优势。

用专业术语来说,唯一能说的是,

  • 派生类是一个基类加上更多的东西
  • 通过基指针引用派生类使得"更多的东西"无法访问,除非基类中有一种机制使您跳转到派生作用域。
  • c++为隐式跳转提供的机制是虚函数。
  • c++为显式跳转提供的机制是dynamic_cast(用于向下转换)。
  • 对于非多态对象(没有任何虚拟方法)static_cast (downcast)仍然可用,但没有运行时检查。

优点和缺点源于对所有这些点的一致和不一致的使用。

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

class A
{
   void foo();
}
class B : public A
{
   void foo2();
}
A* b = new B;
b->foo2(); //error - no longer visible

我在这里讨论的是非虚函数。

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

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