【问题标题】:technical aspects of 'isa' in c++C ++中“isa”的技术方面
【发布时间】:2011-04-20 11:13:20
【问题描述】:

technical point of view 到底是什么意思,我明白这意味着我的derived class 总是可以转换为base class,是吗?我读了一些材料,没有任何技术方面的参考,只有哲学!提前致谢

【问题讨论】:

    标签: c++ principles ooad


    【解决方案1】:

    表示我的派生类总是可以转基类

    实际上它的意思比这更好。 int 始终可以转换为 float,但这并不意味着 int “是”浮点数。它只是意味着可以从 int 构造一个浮点数。同样,您可以拥有可转换但没有其他关系的用户定义类。

    通过继承,派生类的指针或引用总是可以转换为基类的指针或引用[*]。也就是说,派生类的对象可以代替基类的对象。它实际上是其中之一。如果一个人可以代替脑外科医生,那么他们就是脑外科医生。

    如果“是 a”,一个正式的定义是 Barbara Liskov 的 substitution principle。诚然,这仍然是哲学,但它是非常合理的哲学,它与您编写程序的方式直接相关。

    在 C++ 中使用继承时,您必须保持直截了当的另一件事是运行时多态性(使用 virtual 函数实现)和静态多态性(实际上根本不需要继承)之间的区别。对于非虚拟函数调用,被调用函数的版本始终是编译器被告知对象具有的类中定义的版本(静态类型)。如果它在派生类中重载,这实际上可能无法正常工作。对于虚拟调用,调用的版本是对象实际所在的类中定义的版本(动态类型)。您必须确定您的目标是两种“是”中的哪一种。

    [*] 并且对象可以通过指针有效访问,也就是说。你总是可以用reinterpret_cast 强制指针类型,但这不是我的意思。还有一些繁琐的细节——如果基类不明确,那么你不能一次性转换指针,但是你可以使用几个明确的强制转换来明确地做到这一点。如果基类不可访问,那么您可以转换它,但只能使用 C 风格的转换,而不是隐式转换。 C 风格的转换就像 static_cast 一样忽略可访问性,而不像 reinterpret_class。所以你得到了一个工作指针,但希望你也能强烈地感觉到你做错了什么;-)

    【讨论】:

    • 哦,是的。我忘了 LSP 这个词
    • 非常好的解释,非常感谢 Steve Jessop 和 Chubsdad
    【解决方案2】:

    派生类只能在给定点 R 处转换为可访问且明确的基类。除了 C++ 标准本身之外,没有缺乏引用和其他地方。

    $10.2 是一个很好的参考:一个派生的 类本身可以作为基类 受访问控制;见 11.2。一种 指向派生类的指针可以是 隐式转换为指向的指针 可访问的明确基类 (4.10)。派生类的左值 类型可以绑定到对 可访问的明确基类 (8.5.3)。 ——尾注]

    再来一次

    $10.3 - “基本说明符列表 指定基类的类型 对象中包含的子对象 派生类类型。[..] 这里,一个 Derived2 类的对象将有一个 Derived 类的子对象,其中 turn 将有一个类的子对象 基地。[...]

    就OOAD原则而言:

    我个人会推荐 Robert Martin's articles 来很好地掌握这一点,尤其是 OCP 原则。作者解释这些传奇的 OOAD 指南时的清晰性和权威性对我来说是无法超越的

    还可以查看@Steves 帖子中解释的 LSP

    【讨论】:

    • 哎呀!。无论谁投票,请重新检查我的帖子并再次决定投票是否值得。对上一篇文章进行了重大修改(对此进行了投票)
    猜你喜欢
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多