“isa”的技术方面在 c++

发布于 2024-09-25 21:15:35 字数 119 浏览 2 评论 0原文

技术角度来看到底是什么意思,我理解这意味着我的派生类总是可以转换为基类,那就是它?我读了一些材料,没有参考任何技术方面的内容,只有哲学!提前致谢

what exactly does it mean from technical point of view, I understood that it means that my derived class can always be converted to base class, that's it? I read some materials without any reference to technical aspects, only philosophy! thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深居我梦 2024-10-02 21:15:35

这意味着我的派生类总是可以转换为基类

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

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

“是”的一个正式定义是 Barbara Liskov 的替换原则。诚然,这仍然是哲学,但它是非常合理的哲学,它与您如何编写程序直接相关。

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

[*] 并且该对象可以通过指针有效访问,也就是说。您始终可以使用reinterpret_cast强制指针类型,但这不是我在这里的意思。还有一些繁琐的细节 - 如果基类不明确,那么您无法一次性转换指针,但您可以使用几个明确的强制转换显式地完成此操作。如果基类不可访问,那么您可以对其进行转换,但只能使用 C 样式转换,而不是隐式转换。 C 风格的强制转换就像忽略可访问性的static_cast,而不是像reinterpret_class。所以你会得到一个工作指针,但希望你也能强烈意识到你正在做一些非常错误的事情;-)

it means that my derived class can always be converted to base class

Actually it means better than that. int can always be converted to float, but that doesn't mean an int "is a" float. It just means a float can be constructed from an int. Likewise you can have user-defined classes that convert, but have no other relationship.

With inheritance, a pointer or reference to the derived class can always be converted to a pointer or reference to the base class[*]. That is to say, an object of the derived class can stand in place of an object of the base class. It actually is one of those things. If a person can stand in for a brain surgeon, then they're a brain surgeon.

One formal definition if "is a" is Barbara Liskov's substitution principle. Which admittedly is still philosophy, but it's very sound philosophy and it relates directly to how you write programs.

The other thing you have to keep straight when using inheritance in C++ is the difference between runtime polymorphism (achieved using virtual functions) and static polymorphism (which doesn't actually require inheritance at all). With non-virtual function calls, the version of the function called is always the version defined in the class that the compiler is told the object has (the static type). This might not actually work correctly, if it's overloaded in the derived class. With virtual calls, the version called is the version defined in the class the object actually is (the dynamic type). It's essential to decide which of the two kinds of "is a" you're aiming for.

[*] and the object be validly accessible through the pointer, that is. You can always coerce pointer types with reinterpret_cast, but that's not what I mean here. And there are some fiddly details - if the base class is ambiguous then you can't convert the pointer in one go, but you can do it explicitly using several unambiguous casts. If the base class is not accessible then you can convert it, but only with a C-style cast, not implicitly. The C-style cast acts like a static_cast which ignores accessibility, not like a reinterpret_class. So you get a working pointer, but hopefully also a strong sense that you're doing something very wrong ;-)

假情假意假温柔 2024-10-02 21:15:35

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

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

再说一次

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

就 OOAD 原则而言:

我个人推荐 Robert Martin 的文章很好地掌握这一点,尤其是 OCP 原则。对我来说,作者解释这些传奇的 OOAD 指南的清晰度和权威性是无法比拟的。

另请参阅 @Steves 帖子中解释的 LSP

A derived class can be converted to only an accessible and unambiguous base class at a given point R. There is no dearth of references and what other place than the C++ standard itself.

$10.2 is a good reference: A derived
class can itself serve as a base class
subject to access control; see 11.2. A
pointer to a derived class can be
implicitly converted to a pointer to
an accessible unambiguous base class
(4.10). An lvalue of a derived class
type can be bound to a reference to an
accessible unambiguous base class
(8.5.3). —end note ]

And again

$10.3 - "The base-specifier-list
specifies the type of the base class
subobjects contained in an object of
the derived class type.[..] Here, an
object of class Derived2 will have a
subobject of class Derived which in
turn will have a subobject of class
Base.[...]

In terms of OOAD principles:

I would personally recommend Robert Martin's articles for getting a good hold on this especially the OCP principle. It is not possible for me to beat the clarity and authority with which the author explains these legendary OOAD guidelines

Also look at LSP as explained in @Steves' post

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文