technical point of view
究竟是什么意思,我明白这意味着我的derived class
总是可以转换为base class
,就是这样?我读了一些材料,没有任何参考技术方面,只有哲学!提前谢谢
答案 0 :(得分:4)
这意味着我的派生类总是可以转换为基类
实际上它意味着更好。 int
始终可以转换为float
,但这并不意味着int“是”浮点数。它只是意味着可以从int构造一个float。同样,您可以使用用户定义的类进行转换,但没有其他关系。
对于继承,指向派生类的指针或引用始终可以转换为指针或对基类[*]的引用。也就是说,派生类的对象可以代替基类的对象。它实际上就是其中之一。如果一个人可以代替脑外科医生,那么他们就是脑外科医生。
如果“是一个”,一个正式的定义是Barbara Liskov的substitution principle。诚然,这仍然是哲学,但它是非常合理的哲学,它直接与你编写程序的方式有关。
在C ++中使用继承时,你必须保持直接的另一件事是运行时多态(使用virtual
函数实现)和静态多态(实际上根本不需要继承)之间的区别。对于非虚函数调用,所调用函数的版本始终是编译器被告知对象具有的类(静态类型)中定义的版本。如果它在派生类中重载,则实际上可能无法正常工作。对于虚拟调用,调用的版本是对象实际所在的类中定义的版本(动态类型)。决定你所瞄准的两种“是”中的哪一种是至关重要的。
[*]并且可以通过指针有效地访问对象,即。您始终可以使用reinterpret_cast
强制指针类型,但这不是我的意思。并且有一些繁琐的细节 - 如果基类是模糊的,那么你不能一次性转换指针,但你可以使用几个明确的转换显式地做。如果基类不可访问,那么可以转换它,但只能使用C样式转换,而不是隐式。 C风格的演员表现为static_cast
,忽略了辅助功能,而不像reinterpret_class
。所以你得到一个工作指针,但希望你也有一种强烈的感觉,你做的事情非常错误; - )
答案 1 :(得分:2)
派生类只能在给定的点R转换为可访问且明确的基类。除了C ++标准本身之外,没有缺少引用和其他地方。
$ 10.2是一个很好的参考:A派生 class本身可以作为基类 受访问控制;见11.2。一个 指向派生类的指针即可 隐式转换为指向 一个可访问的明确的基类 (4.10)。派生类的左值 type可以绑定到对a的引用 可访问的明确的基类 (8.5.3)。 - 后注]
再次
$ 10.3 - “base-specifier-list 指定基类的类型 包含在对象中的子对象 派生类类型。[..]这里,一个 Derived2类的对象将有一个 类的子对象派生在 转弯将有一个类的子对象 基。[...]
就OOAD原则而言:
我个人会建议Robert Martin's articles对此有所了解,尤其是OCP原则。我不可能超越作者解释这些传奇的OOAD指南的清晰度和权威性
另请参阅@Steves的帖子
中解释的LSP