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

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直接赋值给基类对象aa.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的指针,让它指向bb.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.mzph.cn/web/61979.shtml

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

相关文章

Solana VS 以太坊:基于数据、市场情绪和催化剂对比分析,Solana 能否实现逆袭?

2023年&#xff0c;加密货币市场再度迎来了波动与重塑。在这一轮周期中&#xff0c;Solana&#xff08;SOL&#xff09;凭借其强劲的价格表现和创新的技术架构&#xff0c;成为市场的焦点之一。SOL的价格从2022年12月的低点一路飙升&#xff0c;甚至创下了历史新高264 USDT&…

Mac安装MINIO服务器实现本地上传和下载服务

0.MINIO学习文档 Minio客户端mc使用 | Elibaron学习笔记 1.Mac安装MINIO 中文官方网址&#xff1a;MinIO下载和安装 | 用于创建高性能对象存储的代码和下载内容 (1) brew 安装 brew install minio/stable/minio &#xff08;2&#xff09;安装完成&#xff0c;执行brew i…

el-table 组件二次封装(vue2)

PublicTable.vue <!-- 公共表格组件 --> <template><div class"table-common"><el-table v-loading"loading" :ref"tableid" border style"width: 100%" :data"tableDatas" :row-key"rowKey&quo…

pgsql指令、pg在docker中打开

常规 linux 在安装pgsql的服务器上 root是用户名&#xff0c;test是数据库名 psql -U root -d test登录后显示&#xff0c;12,6是版本号 psql (12.6) 查询所有表 \dt查询表结构 \d table_name查询表所属 \dp manual_logistics_logSELECT n.nspname AS table_schema,c.re…

alpine openssl 编译

./config no-shared --prefix/usr/local/openssl apk add musl-dev gcc g apk add linux-headers ssh root 登录 编辑 SSH 配置文件 打开 SSH 配置文件 /etc/ssh/sshd_config&#xff1a; vi /etc/ssh/sshd_config PermitRootLogin yes

一文解决数据库【事务】相关问题

文章目录 前言一、事务的基本概念二、ACID 特性1.原子性&#xff08;Atomicity&#xff09;2.一致性&#xff08;Consistency&#xff09;3.隔离性&#xff08;Isolation&#xff09;4.持久性&#xff08;Durability&#xff09; 三、事务的操作1.开始事务&#xff08;BEGIN TR…

Mac苹果电脑 java前后端开发环境及软件安装教程

本文记录我初次使用macOS系统&#xff0c;m4 mini安装开发软件及环境的全过程&#xff0c;希望能帮助到你&#xff0c;好用的请点赞评论收藏增加热度&#xff0c;让更多Mac小白轻松体验开发&#xff0c;20241129 …

dfs—acwing

题目一&#xff1a;排序数字 842. 排列数字 - AcWing题库 分析 考虑dfs&#xff0c;其实stl——next_permutation也可以 路径存储开一个数组&#xff0c;不能重复搜索&#xff0c;加一个标记数组 代码 #include<bits/stdc.h> using namespace std;int path[10]; int…

一步一步写线程之十六线程的安全退出之一理论分析

一、多线程的开发 多线程的开发&#xff0c;在实际场景中几乎是无法避开的。即使是前端看似没有使用线程&#xff0c;其实在底层的框架中也使用了线程进行了支撑。至少到现在&#xff0c;不管是协程还是其它什么新的编程方式&#xff0c;仍然无法撼动线程的主流地位。 多线程的…

ISAAC SIM踩坑记录--添加第三方3D场景

ISAAC SIM仿真首先就是要有合适的3D场景&#xff0c;官方提供了一些场景&#xff0c;如果不能满足要求&#xff0c;那就只能自己建。 对于我这种不会3D建模的菜鸟&#xff0c;只能到网上下载了&#xff0c;sketchfab就是一个不错的平台&#xff0c;有不少免费资源可以下载。 …

人工智能_大模型091_大模型工作流001_使用工作流的原因_处理复杂问题_多轮自我反思优化ReAct_COT思维链---人工智能工作笔记0236

# 清理环境信息&#xff0c;与上课内容无关 import os os.environ["LANGCHAIN_PROJECT"] "" os.environ["LANGCHAIN_API_KEY"] "" os.environ["LANGCHAIN_ENDPOINT"] "" os.environ["LANGCHAIN_TRACING_V…

完全按照手册win10里装Ubuntu 虚拟机然后编译ESP32(主要是想针对ESP32C3和S3)开发板的鸿蒙系统(失败)

基本上完全按照手册来的&#xff0c;除了Ubuntu虚拟机使用了22.04 Jammy版本&#xff0c;鸿蒙手册里是20.04 版本&#xff0c;主要是鸿蒙里3年前的手册了&#xff0c;所以就擅自用了高版本。 据此还想到一点&#xff0c;鸿蒙LiteOS&#xff0c;还挺稳定的&#xff0c;3年也没有…

一文理解多模态大语言模型——下

作者&#xff1a;Sebastian Raschka 博士&#xff0c; 翻译&#xff1a;张晶&#xff0c;Linux Fundation APAC Open Source Evangelist 编者按&#xff1a;本文并不是逐字逐句翻译&#xff0c;而是以更有利于中文读者理解的目标&#xff0c;做了删减、重构和意译&#xff0c…

【Leetcode Top 100 - 扩展】328. 奇偶链表

问题背景 给定单链表的头节点 h e a d head head&#xff0c;将所有索引为奇数的节点和索引为偶数的节点分别组合在一起&#xff0c;然后返回重新排序的列表。 第一个 节点的索引被认为是 奇数 &#xff0c; 第二个 节点的索引为 偶数 &#xff0c;以此类推。 请注意&#xf…

使用伪装IP地址和MAC地址进行Nmap扫描

使用伪装IP地址和MAC地址进行Nmap扫描 在某些网络设置中&#xff0c;攻击者可以使用伪装的IP地址甚至伪装的MAC地址进行系统扫描。这种扫描方式只有在可以保证捕获响应的情况下才有意义。如果从某个随机的网络尝试使用伪装的IP地址进行扫描&#xff0c;很可能无法接收到任何响…

k8s 之 Role-Based Access Control

在 Kubernetes 中&#xff0c;RBAC&#xff08;Role-Based Access Control&#xff09;是一个用来控制对 Kubernetes 资源访问的授权机制。它通过定义不同角色&#xff08;Role&#xff09;和这些角色可以访问的权限&#xff0c;确保只有被授权的用户或服务能够执行特定的操作。…

什么是TCP的三次握手?

TCP的三次握手&#xff1a;深入理解建立可靠连接的过程 引言 在计算机网络中&#xff0c;传输控制协议&#xff08;TCP&#xff09;是确保数据可靠传输的核心协议之一。TCP通过三次握手机制来建立一个稳定的、双向的连接&#xff0c;这对于确保数据的完整性和顺序至关重要。本…

SpringBoot该怎么使用Neo4j - 优化篇

文章目录 前言实体工具使用 前言 上一篇中&#xff0c;我们的Cypher都用的是字符串&#xff0c;字符串拼接简单&#xff0c;但存在写错的风险&#xff0c;对于一些比较懒的开发者&#xff0c;甚至觉得之间写字符串还更自在快速&#xff0c;也确实&#xff0c;但如果在后期需要…

MySQL中on和where的区别

select name, bonus from Employee left join Bonus on Employee.EmpId Bonus.EmpId where bonus is null or bonus < 1000 作者&#xff1a;力扣官方题解 链接&#xff1a;https://leetcode.cn/problems/employee-bonus/ 来源&#xff1a;力扣&#xff08;LeetCode&#x…

数据科学与大数据之间的区别

什么是数据科学&#xff1f; 数据科学是一个跨学科领域&#xff0c;它将统计学和计算方法相结合&#xff0c;旨在从数据中提取见解和知识。它涉及收集、处理、分析以及解读数据&#xff0c;以揭示可用于为决策过程提供依据并推动创新的模式、趋势和关系。 数据科学涵盖了广泛…