C++ 父类与派生类关系 隐藏规则

作用域可见性:

    如果存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,那么外层标识符在内层依然可见,如果在内层声明了同名标识符,则外层标识符在内层不可见,这时称内层标识符隐藏了外层同名标识符,这种现象称为隐藏规则。

    在类的派生层次结构中,基类的成员和派生类新增的成员都具有类作用域。二者的作用范围不同,是相互包含的两个层,派生类在内层。这时,如果派生类声明了一个和某个基类成员同名的新成员,派生的新成员就隐藏了外层同名成员,直接使用成员名只能访问到派生类的成员。如果派生类中声明了与基类同名的新函数,即使函数的参数表不同,从基类继承的同名函数的所有重载形式也都被隐藏。如果要访问被隐藏的成员,就需要使用类作用域分辨符和基类名来限定。

父类处于外层,派生类处于内层。


客户端代码:


最后结果:


从以上输出,可以得出:关于C++隐藏规则部分,因为内层也就是子类对printf1和printf2进行了重新声明定义,所以,子类调用的是子类作用域的函数,并没有调用外层即父类的函数。而父类则处于作用域外层,那么派生类的方法对于其是不可见的,隐藏的,调用的也是父类自己的函数。

在派生类中,如果有对和父类同名函数进行重新声明定义,那父类函数将被隐藏,派生类无法调用,否则父类函数就不会被隐藏。

### C++派生类的继承规则 #### 单继承中的成员访问控制 当一个类通过 `public` 方式从另一个类继承时,基类中的公有成员在派生类中仍然是公有的;保护成员保持为受保护的状态;而私有成员则不可被派生类直接访问。如果采用的是 `protected` 或者 `private` 的继承方式,则会改变这些成员的可访问性[^2]。 #### 构造函数析构函数的行为 对于单继承结构下的派生类,在创建对象时先调用基类构造函数初始化基类部分的数据成员,之后再执行自身的构造逻辑来设置新增加的内容。相反地,在销毁对象的时候顺序正好相反——先是清理派生出来的特性,最后才处理基础属性[^1]。 #### 虚拟继承解决菱形问题 为了避免因多条路径导致同一个基类多次嵌入到最终派生类里所造成的二义性和浪费空间的情况(即所谓的“菱形继承”),C++ 提供了虚拟继承机制。声明为virtual base classes 的祖先只会有一份副本存在于最末端后代之中[^3]。 #### 成员覆盖隐藏现象 考虑这样一个场景:父类和子类各自定义了一个同名的方法或者变量。按照就近原则,默认情况下编译器会选择最近的作用域内的版本作为实际使用的实体。但是需要注意的是,这并不意味着旧版就被完全替代掉了,而是处于一种被遮蔽的状态。可以通过作用域解析运算符显式指定要调用哪一个版本的方法或访问哪个字段[^5]。 ```cpp class Base { public: void show() const { std::cout << "Base\n"; } }; class Derived : public Base { public: void show() const override { std::cout << "Derived\n"; } // 显示覆写标记 }; ``` 上述代码展示了如何利用 `override` 关键字明确指出当前方法意图重载自基类相应签名的方法,并且提供了更好的错误检测能力以防止意外情况发生。 #### 抽象类的应用场合 某些时候希望构建一些无法具体化的概念模型,这时就可以借助于纯虚函数的概念形成抽象类。任何含有至少一个未实现接口(也就是只有声明没有主体定义)的类都会自动成为此类别的一员。由于缺乏完整的功能实现细节,因此不允许直接实例化这样的模板,但允许基于它建立具体的衍生类型并提供必要的行为填充[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值