C++——名字遮蔽与类的作用域

news2024/12/26 9:08:52

C++ 类的作用域以及继承的特殊关系

  • 名字遮蔽与类的作用域
  • 继承的特殊关系

名字遮蔽与类的作用域

如果派生类中的成员(包括成员变量和成员函数)和基类中的成员重名,通过派生类对象或者在派生类的成员函数中使用该成员时,将使用派生类新增的成员,而不是基类的。
注意基类的成员函数和派生类的成员函数不会构成重载。如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数。
类是一种作用域,每个类都有它自己的作用域,在这个作用域之内定义成员。
在类的作用域之外,普通的成员只能通过对象(可以是对象本身,也可以是对象指针或对象引用)来访问,静态成员可以通过对象访问,也可通过访问。
成员名前面类名域解析符可以访问对象的成员。
如果不存在继承关系,类名域解析符省略不写。
代码如下:

#include <iostream>

using namespace std;

class A
{
    public:
        int a_ = 123;
        int b_ = 456;
        void func() {cout << "调用 A 的 func() 函数" << endl;}
        void func(int n) {cout << "调用 A 的 func(int n) 函数" << endl;}
};

int main() {
    A a;
    cout << "a 的成员 a_ = " << a.a_ << endl;
    cout << "a 的成员 b_ = " << a.A::b_ << endl;
    a.func();
    a.A::func(1);

    return 0;
}

编译运行结果如下:

a 的成员 a_ = 123
a 的成员 b_ = 456
调用 A 的 func() 函数
调用 A 的 func(int n) 函数

当存在继承关系时,基类的作用域嵌套派生类的作用域中。如果成员派生类作用域中已经找到,就不会基类作用域中继续查找;如果没有找到,则继续基类作用域中查找。
如果在成员的前面加上类名域解析符,就可以直接使用该作用域的成员。
示例代码如下:

#include <iostream>

using namespace std;

class A // 基类
{
    public:
        int a_ = 111;
        void func() {cout << "调用基类 A 的 func() 函数" << endl;}
};

class B:public A // 子类
{
    public:
        int a_ = 222;
        void func() {cout << "调用子类 B 的 func() 函数" << endl;}
};

class C:public B // 孙类
{
    public:
        int a_ = 333;
        void func() {cout << "调用孙类 C 的 func() 函数" << endl;}
        void show() {
            cout << "C::a_ = " << C::a_ << endl;
            cout << "B::a_ = " << B::a_ << endl;
            cout << "A::a_ = " << A::a_ << endl;
        }
};


int main() {
    C c;
    c.show();
    c.C::func();
    c.B::func();
    c.A::func();

    return 0;
}

编译运行结果如下:

C::a_ = 333
B::a_ = 222
A::a_ = 111
调用孙类 C 的 func() 函数
调用子类 B 的 func() 函数
调用基类 A 的 func() 函数

继承的特殊关系

派生类和基类之间有一些特殊关系。

  1. 如果继承方式是公有的,派生类对象可以使用基类成员。
  2. 可以把派生类对象复制给基类对象(包括私有成员),但是,会舍弃非基类的成员。
#include <iostream>

using namespace std;

class A {
    public:
        int a_ = 0;
    private:
        int b_ = 0;
    public:
        void show() {cout << "A::show() a = " << a_ << ", b = " << b_ << endl; }
        void setb(int b) {b_ = b;}
};

class B : public A {
    public:
        int c_ = 0;
        void show() {
            cout << "B::show() a = " << a_ << " c = " << c_ << endl;
        }
};

int main() {
    A a;
    B b;

    b.a_ = 1;
    b.setb(2); // 通过公有成员函数访问修改基类私有成员
    b.c_ = 3;

    a.show();
    a = b; // 派生类对象b直接赋值给基类对象a
    a.show();

    return 0;
}

编译运行结果如下:

A::show() a = 0, b = 0
A::show() a = 1, b = 2

  1. 基类指针可以在不进行显式转换的情况下指向派生类对象。

示例代码如下:

#include <iostream>

using namespace std;

class A {
    public:
        int a_ = 0;
    private:
        int b_ = 0;
    public:
        void show() {cout << "A::show() a = " << a_ << ", b = " << b_ << endl; }
        void setb(int b) {b_ = b;}
};

class B : public A {
    public:
        int c_ = 0;
        void show() {
            cout << "B::show() a = " << a_ << " c = " << c_ << endl;
        }
};

int main() {
    B b;
    A *a = &b; // 声明类A的指针,让它指向b

    b.a_ = 1;
    b.setb(2); // 通过公有成员函数访问修改基类私有成员
    b.c_ = 3;
    b.show();
    
    // 在c++中,数据类型决定了操作数据的方法。
    // 现在a是A类的指针,在这个程序中,不管a指向谁,只会按A类的方法来操作数据。
    a->a_ = 111;
    a->setb(222);
    // a->c_ = 333; // 基类A没有c_这个成员 代码错误
    a->show();

    return 0;
}

编译运行的结果如下:

B::show() a = 1 c = 3
A::show() a = 111, b = 222

  1. 基类引用可以在不进行显式转换的情况下引用派生类对象。
  2. 基类指针或引用只能调用基类的方法,不能调用派生类的方法。
  3. 可以用派生类构造基类。
  4. 如果函数的形参是基类,实参可以用派生类。
  5. C++要求指针和引用类型与赋给的类型匹配,这一规则对继承来说是例外。但是,这种例外只是单向的,不可以将基类对象和地址赋给派生类引用和指针。

感谢浏览,一起学习!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2253948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

100V降压恒流芯片SL2516D 内置MOS管 支持15W功率输出 电动车照明

一、SL2516D芯片概述 SL2516D是一款新一代车灯照明专用降压恒流IC&#xff0c;支持高达100V的输入电压范围&#xff0c;并内置了100V功率MOS。它采用ESOP8封装&#xff0c;具有外围电路简单、高效能、高精度和稳定的恒流输出特性。 二、内置MOS管 SL2516D芯片内置了100V功率…

Microi吾码|.NET、VUE快速搭建项目,低代码便捷开发教程

Microi吾码&#xff5c;VUE快速搭建项目&#xff0c;低代码便捷开发教程 一、摘要二、Microi吾码介绍2.1 功能介绍2.2 团队介绍2.3 上线项目案例 三、VUE中使用Microi吾码3.1 前期了解3.2 创建第一个低代码应用3.3 接口API使用说明3.4 引擎界面可视化配置&#xff0c;生成API3.…

线程信号量 Linux环境 C语言实现

既可以解决多个同类共享资源的互斥问题&#xff0c;也可以解决简易的同步问题 头文件&#xff1a;#include <semaphore.h> 类型&#xff1a;sem_t 初始化&#xff1a;int sem_init(sem_t *sem, int pshared, unsigned int value); //程序中第一次对指定信号量调用p、v操…

解决 Maven 部署中的 Artifact 覆盖问题:实战经验分享20241204

&#x1f6e0;️ 解决 Maven 部署中的 Artifact 覆盖问题&#xff1a;实战经验分享 &#x1f4cc; 引言 在软件开发过程中&#xff0c;持续集成和持续部署&#xff08;CI/CD&#xff09;是提高开发效率和代码质量的关键手段。Hudson 和 Maven 是两种广泛使用的工具&#xff0…

【Linux】文件描述符fd

1.前置预备 文件 内容 属性访问文件之前&#xff0c;都必须先打开他 #include<stdio.h> int main() { FILE* fpfopen("log.txt","w"); if(fpNULL) { perror("fopen"); return 1; } fclose(fp); return 0…

JVM 性能调优 -- JVM 调优常用网站

前言&#xff1a; 上一篇分享了 JDK 自带的常用的 JVM 调优命令和图形化界面工具&#xff0c;本篇我们分享一下常用的第三方辅助 JVM 调优网站。 JVM 系列文章传送门 初识 JVM&#xff08;Java 虚拟机&#xff09; 深入理解 JVM&#xff08;Java 虚拟机&#xff09; 一文搞…

数据结构自测5

第6章 树和二叉树 自测卷解答 一、下面是有关二叉树的叙述&#xff0c;请判断正误&#xff08;每小题1分&#xff0c;共10分&#xff09; &#xff08; √ &#xff09;1. 若二叉树用二叉链表作存贮结构&#xff0c;则在n个结点的二叉树链表中只有n—1个非空指针域。 &#xff…

优傲协作机器人 Remote TCP Toolpath URCap(操作记录)

目录 一、新机设置项 1、设置管理员密码 2、设置安全密码 3、设置负载 二、激活 Remote TCP & Toolpath URCap 1、插入U盘 2、打开激活面板 3、导入许可证 4、查看是否激活成功 5、启用功能 三、使用流程&#xff08;官方&#xff09; 步骤一 步骤二 步骤三 …

【数据库系列】Spring Boot如何配置Flyway的回调函数

Flyway 提供了回调机制&#xff0c;使您能够在特定的数据库迁移事件发生时执行自定义逻辑。通过实现 Flyway 的回调接口&#xff0c;可以在迁移前后执行操作&#xff0c;如记录日志、执行额外的 SQL 语句等。 1. 创建自定义回调类 要配置 Flyway 的回调函数&#xff0c;需要创…

正点原子imx6ull配置MQTT客户端上传数据到Ubuntu MQTT服务器

目录 使用QT自带的MQTT模块部署客户端创建一个class专门用于MQTT客户端通讯使用QT在ui界面上生成按钮在Windows上订阅相应主题测试在imx6ull上订阅Windows发布的消息 在上一篇中介绍了在Ubuntu22.04的Docker中部署MQTT服务器&#xff0c;然后在window上测试订阅和发布&#xff…

3D数据大屏实现过程,使用echarts、Next.js

&#x1f4dc; 本文主要内容 数据大屏自适应方案动效 echarts&#xff1a; 3D 立体柱状图动态流光折线图 3D 地球&#xff08;飞线、柱状图&#xff09;无限滚动列表 &#x1f50d; 大屏效果 数据大屏&#xff1a; 点击预览 &#x1f579; 运行条件 next 12.3.4echarts 5.4…

第一部分 网络安全

网络安全是利用各种网络监控和管理技术措施&#xff0c;对网络系统的硬件、软件及系统中的数据源实施保护&#xff0c;使其不会因为一些不利因素遭到破坏&#xff0c;从而保证网络系统连续、安全、可靠的运行。 一、信息泄露与篡改 四种类型&#xff1a;截获信息&#xff0c;…

机器学习--绪论

开启这一系列文章的初衷&#xff0c;是希望搭建一座通向机器学习世界的桥梁&#xff0c;为有志于探索这一领域的读者提供系统性指引和实践经验分享。随着人工智能和大数据技术的迅猛发展&#xff0c;机器学习已成为推动技术创新和社会变革的重要驱动力。从智能推荐系统到自然语…

家庭财务管理系统的设计与实现ssm小程序+论文源码调试讲解

2系统关键技术 2.1 微信小程序 微信小程序&#xff0c;简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种全新的连接用户与服务的方式&#xff0c;可以快速访问、快速传播&#xff0c;并具有良好的使用体验。 小程序的主要开发语言是JavaScript&#xff0c;它与普…

MySQL初学之旅(5)详解查询

目录 1.前言 2.正文 2.1聚合查询 2.1.1count() 2.1.2sum() 2.1.3avg() 2.1.4max() 2.1.5min() 2.1.6总结 2.2分组查询 2.2.1group by字句 2.2.2having字句 2.2.3group by与having的关系 2.3联合查询 2.3.1笛卡尔积 2.3.2内连接 2.3.3外连接 2.3.4自连接 2.3…

Java Web 2 JS Vue快速入门

一 JS快速入门 1.什么是JavaScript&#xff1f; 页面交互&#xff1a; 页面交互是指用户与网页之间的互动过程。例如&#xff0c;当用户点击一个按钮&#xff0c;网页会做出相应的反应&#xff0c;如弹出一个对话框、加载新的内容或者改变页面的样式等&#xff1b;当用户在表…

浅谈MySQL路由

华子目录 mysql-router介绍下载mysql-router安装mysql-router实验 mysql-router介绍 mysql-router是一个对应用程序透明的InnoDB Cluster连接路由服务&#xff0c;提供负载均衡、应用连接故障转移和客户端路由利用路由器的连接路由特性&#xff0c;用户可以编写应用程序来连接到…

Python语法基础---正则表达式

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 我们这个文章所讲述的&#xff0c;也是数据分析的基础文章&#xff0c;正则表达式 首先&#xff0c;我们在开始之前&#xff0c;引出一个问题。也是我们接下来想要解决的问题。…

AMEYA360 | 杭晶电子:晶振在AR/VR中的应用

晶振在AR/VR设备中扮演重要角色&#xff0c;为其核心电子系统提供稳定的时钟信号&#xff0c;确保设备的高性能运行。 以下是晶振在AR/VR应用中的具体作用&#xff1a; 01、图像处理与同步 1、晶振为图形处理单元(GPU)和显示芯片提供精准的时钟信号&#xff0c;支持高速图像渲染…

如何将python项目导出为docker镜像

如何将python项目导出为docker镜像 前提条件步骤 1: 创建并准备 Python 项目步骤 2: 创建 `setup.py`步骤 3: 打包项目步骤 4: 创建 Dockerfile步骤 5: 构建 Docker 镜像步骤 6: 运行 Docker 容器步骤 7: 保存修改并继续开发总结要将修改后的Python代码导出为 .tar.gz 格式,并…