需要一些帮助来理解类继承(C++)

Need some assist to understand class inheritance (C++)

本文关键字:继承 C++ 帮助      更新时间:2023-10-16

我正在尝试出于自己的目的扩展其他人的API,并且我试图在该上下文中了解类继承。

我写了这个最小的程序:

#include 类 first_class { 公共: first_class() {}; }; 类 second_class : first_class { 私人: 国际 y; 公共: int get_y() { return y; } second_class() { y=99; } }; int main() { first_class* a = 新 first_class(); second_class* b = 新second_class(); int q = ((second_class*)a)->get_y(); printf("%d",q); int r = b->get_y(); printf("%d",r); }

first_class 什么都不做,也没有成员。 second_class继承自first_class,但添加一个私有成员 y 和一个 getter 函数 get_y();

当我在 second_class 实例上调用 get_y() 时,它按预期工作。当我在 first_class 实例上调用 get_y() 时,我已将其转换为 second_class,它返回 0。

这是应该预料到的吗?是否所有仅限子类的成员变量都自动设置为零,或者这是编译器有时会执行的通常发生但实际上没有保证的事情之一,并且实际上应该将它们视为未定义?

当你投射一个指针时,它不会"转换"指向的对象(也不会以任何方式影响它)。这是一个noop,即运行时什么也没发生。

相反,它只是改变了所指物体的类型。这是一个编译时概念。

因此,当您编写:

(second_class*)a

你说:"我真的知道a所指的记忆是一个second_class的对象,我想这样访问它"。

但事实并非如此,这是一个first_class.因此,访问y数据成员没有意义。编译器最终很可能会生成最终读取不应读取内存的代码。


现在,有一种方法可以通过基类调用成员函数,即通过实际对象的基类的指针或引用。您可以阅读有关它的信息(子类型,多态性和动态调度是您可能想要阅读的主题)。但在C++中,它需要:

  • 你通过类(而不是像你在这里所做的那样的派生类)访问;即向上转换与向下转换。
  • 类层次结构就是这样使用的。通常,方法和析构函数将在整个层次结构中virtual(示例中没有)。

例如,请参阅:为什么我们需要C++中的虚函数?开始学习它。

这是应该预料到的吗?

否,((second_class*)a)->get_y();调用未定义的行为

是否所有仅子类成员变量都自动设置为零, 或者这是通常发生但实际上无法保证的那些之一 编译器有时会做的事情

两者都不是,您正在有效地读取不属于该对象的内存。任何事情都可能发生(因此未定义的行为)