抽象类的目的不是让开发人员创建基类的对象,然后 upcast 它,AFAIK。
现在,即使不需要向上转播,我仍然使用它,它是否会以某种方式证明“不利”?
更多澄清:
来自C ++中的思考:
通常在设计中,您希望基类只显示一个 其派生类的接口。也就是说,你不希望任何人 实际上创建了一个基类的对象,只是为了向上转换它 它的界面可以使用。这是通过制作该课程来实现的 摘要,
通过向上转发,我的意思是:baseClass *obj = new derived ();
答案 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
现在,如果*p
是Apple
或Blackberry
的实例,您永远不会知道(没有任何手动机制)。
[请注意,非多态类不允许使用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 ++是一种“实用的语言”,它通常不是一种优势,它迫使它适应“唯一的范式”。
在技术方面,唯一可以说的是,
dynamic_cast
(用于向下转换)。static_cast
(向下转发)仍然可用,但没有运行时检查。优点和缺点源于所有这些点的一致和不一致的使用。这不仅仅与垂头丧气有关。