【C++类和数据抽象】类的作用域

目录

一、类的作用域基本概念

1.1 什么是类的作用域

1.2 作用域层次体系

1.3 类作用域的特点

1.4 基本访问规则

二、访问控制三剑客

2.1 public:开放接口

2.2 private:数据封装 

2.3 protected:继承通道

2.4 跨作用域访问示例 

三、类作用域中的成员查找规则

3.1 基本查找规则

3.2 示例代码

3.3 静态成员的特殊作用域

四、在类的外部访问类的成员

4.1 通过对象访问

4.2 通过类名访问静态成员

五、嵌套类

5.1 嵌套类的定义

5.2 嵌套类的访问权限

5.3 嵌套类的作用

六、局部类

6.1 局部类的定义

6.2 局部类的特点

6.3 局部类的用途

七、类作用域与继承

7.1 基类和派生类的作用域关系

7.2 作用域解析运算符在继承中的应用

八、友元与作用域突破

8.1 友元函数

8.2 友元类

九、作用域解析运算符(::)

9.1 解决命名冲突

9.2 全局作用域访问  

十、总结

十一、参考资料


在 C++ 编程中,作用域是一个非常重要的概念,它决定了标识符(如变量、函数、类等)的可见性和生命周期。类的作用域是一种特殊的作用域,它为类的成员(包括成员变量和成员函数)提供了一个独立的命名空间。理解类的作用域对于正确使用类和避免命名冲突至关重要。

一、类的作用域基本概念

1.1 什么是类的作用域

类的作用域是指类定义的大括号内的范围。在这个范围内,类的成员(成员变量和成员函数)具有特定的可见性和访问规则。类的作用域为类的成员提供了一个独立的命名空间,使得不同类的成员可以使用相同的名称而不会产生命名冲突。例如,有两个类ClassAClassB,它们都可以有一个名为func的成员函数,因为它们处于不同的类作用域中。

1.2 作用域层次体系

C++作用域分为六个层级:

作用域类型可见范围生命周期
全局作用域整个程序程序运行期间
命名空间作用域命名空间内部程序运行期间
类作用域类定义内部类存在期间
局部作用域函数/代码块内部代码块执行期间
语句作用域控制语句内部(如for循环)语句执行期间
函数参数作用域函数参数列表函数调用期间

1.3 类作用域的特点

  • 成员的可见性:类的成员在类的作用域内是可见的,但在类的外部通常需要通过对象或类名来访问。
  • 嵌套作用域:类的作用域可以嵌套,例如类中可以定义嵌套类,嵌套类有自己独立的作用域。
  • 命名空间隔离:类的作用域将类的成员与外部作用域的标识符隔离开来,减少了命名冲突的可能性。

1.4 基本访问规则

class MyClass {int privateVar;       // 类作用域内可见static const int MAX = 100; // 类作用域常量
public:void publicMethod() {privateVar = 42;  // 允许访问同类的私有成员}
};int main() {MyClass obj;obj.publicMethod();   // 正确:通过对象访问公有方法// obj.privateVar = 5; // 错误:私有成员不可外部访问return 0;
}

二、访问控制三剑客

2.1 public:开放接口

class API {
public:void openInterface() { /*...*/ }  // 对外开放的服务接口
};

2.2 private:数据封装 

class BankAccount {double balance;       // 私有数据成员
public:void deposit(double amount) {balance += amount; // 内部操作私有数据}
};

2.3 protected:继承通道

class Vehicle {
protected:int speed;            // 受保护成员
};class Car : public Vehicle {
public:void accelerate() {speed += 10;      // 派生类可访问protected成员}
};

2.4 跨作用域访问示例 

class AccessControl {
public:int publicVar;protected:int protectedVar;private:int privateVar;
};class Derived : public AccessControl {void accessDemo() {publicVar = 1;      // ✅protectedVar = 2;   // ✅// privateVar = 3;  // ❌}
};void externalAccess() {AccessControl obj;obj.publicVar = 1;      // ✅// obj.protectedVar = 2;// ❌// obj.privateVar = 3;  // ❌
}

三、类作用域中的成员查找规则

3.1 基本查找规则

当在类的成员函数中使用一个标识符时,编译器会按照以下顺序进行查找:

  • 首先在当前成员函数的局部作用域中查找该标识符。
  • 如果在局部作用域中没有找到,则在类的作用域中查找,即查找类的成员变量和成员函数。
  • 如果在类的作用域中也没有找到,则在包含该类定义的外部作用域中查找。

3.2 示例代码

#include <iostream>
using namespace std;int x = 10;class MyClass {
private:int x = 20;
public:void func() {int x = 30;cout << "Local x: " << x << endl;  // 输出局部变量x的值30cout << "Class member x: " << this->x << endl;  // 输出类成员变量x的值20cout << "Global x: " << ::x << endl;  // 输出全局变量x的值10}
};int main() {MyClass obj;obj.func();return 0;
}

func函数内部有一个局部变量x,类MyClass有一个成员变量x,同时还有一个全局变量x。通过不同的访问方式,可以分别访问到这三个不同作用域的x

3.3 静态成员的特殊作用域

①静态成员特性

  • 类级别而非对象级别
  • 通过类名直接访问
  • 内存中仅存在一份副本

② 代码示例

class Counter {
public:static int count;     // 声明静态成员Counter() { count++; }
};int Counter::count = 0;   // 定义静态成员int main() {Counter a, b;cout << a.count;      // 输出2(通过对象访问)cout << Counter::count; // 输出2(通过类名访问)
}

③静态函数限制

  • 只能访问静态成员变量
  • 不能使用this指针
  • 常用于工具函数或工厂方法

四、在类的外部访问类的成员

4.1 通过对象访问

对于非静态成员变量和成员函数,可以通过类的对象来访问。例如:

#include <iostream>
using namespace std;class Rectangle {
private:int width;int height;
public:Rectangle(int w, int h) : width(w), height(h) {}int getArea() {return width * height;}
};int main() {Rectangle rect(5, 3);cout << "Area: " << rect.getArea() << endl;return 0;
}

通过rect对象调用getArea成员函数来计算矩形的面积。

4.2 通过类名访问静态成员

对于静态成员变量和成员函数,可以通过类名直接访问,不需要创建对象。例如: 

#include <iostream>
using namespace std;class Counter {
public:static int count;static void increment() {count++;}
};int Counter::count = 0;int main() {Counter::increment();cout << "Count: " << Counter::count << endl;return 0;
}

通过Counter类名直接调用increment静态成员函数,并访问count静态成员变量。

五、嵌套类

5.1 嵌套类的定义

嵌套类是指在一个类的内部定义的另一个类。嵌套类的作用域被包含在外部类的作用域内。例如: 

#include <iostream>
using namespace std;class OuterClass {
private:int outerData;
public:OuterClass(int data) : outerData(data) {}class InnerClass {private:int innerData;public:InnerClass(int data) : innerData(data) {}void display() {cout << "Inner data: " << innerData << endl;}};void createInner() {InnerClass inner(10);inner.display();}
};int main() {OuterClass outer(20);outer.createInner();return 0;
}

InnerClassOuterClass的嵌套类。

5.2 嵌套类的访问权限

嵌套类可以访问外部类的静态成员,但通常不能直接访问外部类的非静态成员。外部类对嵌套类的成员的访问也受到嵌套类的访问控制规则的限制。

5.3 嵌套类的作用

嵌套类可以用于将相关的类组织在一起,提高代码的可读性和可维护性。同时,嵌套类可以隐藏一些实现细节,只向外部暴露必要的接口。

六、局部类

6.1 局部类的定义

局部类是指在函数内部定义的类。局部类的作用域仅限于定义它的函数内部。例如: 

#include <iostream>
using namespace std;void func() {class LocalClass {private:int data;public:LocalClass(int d) : data(d) {}void display() {cout << "Local class data: " << data << endl;}};LocalClass obj(5);obj.display();
}int main() {func();return 0;
}

LocalClass是在func函数内部定义的局部类。

6.2 局部类的特点

  • 作用域限制:局部类只能在定义它的函数内部使用,不能在函数外部访问。
  • 成员限制:局部类只能访问函数的静态变量和全局变量,不能访问函数的非静态局部变量。

6.3 局部类的用途

局部类可以用于实现一些只在特定函数内部使用的功能,避免在全局作用域中引入不必要的类定义,提高代码的封装性。

七、类作用域与继承

7.1 基类和派生类的作用域关系

在继承关系中,派生类的作用域嵌套在基类的作用域之上。派生类可以访问基类的公共和受保护成员,同时可以定义自己的成员。当派生类和基类有同名的成员时,派生类的成员会隐藏基类的成员。例如: 

#include <iostream>
using namespace std;class Base {
public:void func() {cout << "Base class func" << endl;}
};class Derived : public Base {
public:void func() {cout << "Derived class func" << endl;}
};int main() {Derived d;d.func();  // 调用派生类的func函数d.Base::func();  // 调用基类的func函数return 0;
}

Derived类和Base类都有一个名为func的成员函数,通过不同的调用方式可以分别调用派生类和基类的func函数。

7.2 作用域解析运算符在继承中的应用

作用域解析运算符::可以用于明确指定要访问的是基类的成员还是派生类的成员,避免成员隐藏带来的混淆。

八、友元与作用域突破

8.1 友元函数

class Secret {int code;friend void crackCode(Secret& s); // 声明友元
};void crackCode(Secret& s) {s.code = 42;  // 友元函数可访问私有成员
}

8.2 友元类

class Safe {int password;friend class Hacker;
};class Hacker {
public:void steal(Safe& s) {s.password = 123456; // 友元类访问私有成员}
};

九、作用域解析运算符(::)

9.1 解决命名冲突

class File {
public:int size;void print(int size) {cout << "File size: " << File::size; // 明确访问类成员cout << "Local size: " << size;      // 参数变量}
};

9.2 全局作用域访问  

int globalVar = 100;class ScopeTest {
public:void show() {int globalVar = 200;cout << ::globalVar; // 输出100(访问全局变量)}
};

十、总结

类的作用域是 C++ 中一个重要的概念,它为类的成员提供了独立的命名空间,决定了成员的可见性和访问规则。理解类的作用域的基本概念、成员查找规则、嵌套类和局部类的使用,以及类作用域在继承中的应用,对于编写高质量的 C++ 代码至关重要。通过合理利用类的作用域,可以提高代码的可读性、可维护性和封装性,避免命名冲突和意外的访问错误。

十一、参考资料

  •  《C++ Primer(第 5 版)》这本书是 C++ 领域的经典之作,对 C++ 的基础语法和高级特性都有深入讲解。
  • 《Effective C++(第 3 版)》书中包含了很多 C++ 编程的实用建议和最佳实践。
  • 《C++ Templates: The Complete Guide(第 2 版)》该书聚焦于 C++ 模板编程,而using声明在模板编程中有着重要应用,如定义模板类型别名等。
  • C++ 官方标准文档:C++ 标准文档是最权威的参考资料,可以查阅最新的 C++ 标准(如 C++11、C++14、C++17、C++20 等)文档。例如,ISO/IEC 14882:2020 是 C++20 标准的文档,可从相关渠道获取其详细内容。
  • :这是一个非常全面的 C++ 在线参考网站,提供了详细的 C++ 语言和标准库文档。
  • :该网站提供了系统的 C++ 教程,配有丰富的示例代码和清晰的解释,适合初学者学习和理解相关知识。
  • 《C++标准库(第2版)》Nicolai M. Josuttis 著

  • Effective STL Scott Meyers 著

  • C++ Core Guidelines:C++ Core Guidelines

  • C++ Reference:https://en.cppreference.com/w/


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

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

相关文章

opencv图片颜色识别,颜色的替换

图片颜色识别 1. RGB颜色空间2. 颜色加法2.1使用numpy对图像进行加法2.2使用opencv加法&#xff08;cv2.add&#xff09; 3 颜色加权加法&#xff08;cv2.addWeighted()&#xff09;4. HSV颜色空间5. 制作掩膜4. 与运算&#xff08;cv2.bitwise_and&#xff09;5.颜色的替换7 R…

ADC数据不稳定的解决方案

问题如图&#xff1a; 解决方案&#xff1a;上图第一个通道后来接入GND&#xff0c;就稳定了 上图第一个通道后来接入VCC&#xff0c;就稳定了

Spark(18)Yarn-概述

Hadoop三大核心组件&#xff1a;HDFS、MapReduce和YARN 一&#xff09;Yarn的概念 YARN(Yet Another Resource Negotiator,另一种资源协调者)是一个通用资源管理系统和调度平台&#xff0c;可为上层应用提供统一的资源管理和调度。它的引入为集群在利用率&#xff0c;资源统一管…

Flowith AI,解锁下一代「知识交易市场」

前言 最近几周自媒体号都在疯狂推Manus&#xff0c;看了几篇测评后&#xff0c;突然在某个时间节点&#xff0c;在特工的文章下&#xff0c;发现了很小众的Flowith。 被这段评论给心动到&#xff0c;于是先去注册了下账号。一翻探索过后&#xff0c;发现比我想象中要有趣的多&…

Maxscript调用Newtonsoft.Json解析Json

Maxscript调用Newtonsoft.Json解析Json_newtonsoft.json maxscript-CSDN博客

搭建用友U9Cloud ERP及UAP IDE环境

应用环境 Microsoft Windows 10.0.19045.5487 x64 专业工作站版 22H2Internet Information Services - 10.0.19041.4522Microsoft SQL Server 2019 - 15.0.2130.3 (X64)Microsoft SQL Server Reporing Services 2019 - 15.0.9218.715SQL Server Management Studio -18.6 laster…

github新建一个远程仓库并添加了README.md,本地git仓库无法push

1.本地git仓库与远程仓库绑定 2.push时报错&#xff0c;本地的 main 分支落后于远程仓库的 main 分支&#xff08;即远程有更新&#xff0c;但你本地没有&#xff09;&#xff0c;需要拉取远程的仓库--->在merge合并&#xff08;解决冲突&#xff09;--->push 3.但是git …

我用deepseek做了一个提取压缩文件夹下pdf和word文件工具

由于最近需要把大量的压缩文件的pdf和word文件统一复制到一个文件夹中。 我们一般正常操作方式的是把一个压缩文件一个一个解压&#xff0c;然后在把一个的解压好的文件夹下文件复制到另外一个文件夹中。 这个也需太繁琐了&#xff0c;从以往统计的需要花费两个小时间&#x…

企业网络安全合规风险高、运营不稳定,要怎么解决?

在数字化浪潮中&#xff0c;数据已然成为企业的核心资产&#xff0c;其重要性不言而喻。然而&#xff0c;数据泄露风险也时刻威胁着企业的生存与发展。不少企业在历经数据泄露的惨痛教训后&#xff0c;纷纷选择部署数据防泄露系统。那么&#xff0c;企业部署数据防泄露系统前后…

C#—Lazy<T> 类型(延迟初始化/懒加载模式)

C# 的 Lazy<T> 类型 Lazy<T> 是 C# 中的一个类&#xff0c;用于实现延迟初始化&#xff08;懒加载&#xff09;模式。它提供了一种线程安全的方式来延迟创建大型或资源密集型对象&#xff0c;直到第一次实际需要时才进行初始化。 主要特点 延迟初始化&#xff1a…

C++之unordered封装

目录 一、哈希表的修改 1.1、哈希表节点结构 1.2、迭代器 1.3、哈希表结构 1.4、完整代码 二、unordered_map的实现 二、unordered_set的实现 一、哈希表的修改 注意&#xff1a;这里我们使用哈希桶来封装unordered_map和unordered_set。 1.1、哈希表节点结构 templa…

[渗透测试]渗透测试靶场docker搭建 — —全集

[渗透测试]渗透测试靶场docker搭建 — —全集 对于初学者来说&#xff0c;仅仅了解漏洞原理是不够的&#xff0c;还需要进行实操。对于公网上的服务我们肯定不能轻易验证某些漏洞&#xff0c;否则可能触犯法律。这是就需要用到靶场。 本文主要给大家介绍几种常见漏洞对应的靶场…

Docker如何更换镜像源提高拉取速度

在国内&#xff0c;由于网络政策和限制&#xff0c;直接访问DockerHub速度很慢&#xff0c;尤其是在拉取大型镜像时。为了解决这个问题&#xff0c;常用的方法就是更换镜像源。本文将详细介绍如何更换Docker镜像源&#xff0c;并提供当前可用的镜像源。 换源方法 方法1&#x…

第一篇:从哲学到管理——实践论与矛盾论如何重塑企业思维

引言&#xff1a;当革命哲学照亮现代商业 1937年&#xff0c;毛泽东在战火中写就的《实践论》《矛盾论》&#xff0c;为中国共产党提供了认识世界的方法论。今天&#xff0c;这两部著作正成为企业破解管理困局的“思维操作系统”&#xff1a; 战略模糊&#xff1a;据Gartner统…

云原生--基础篇-2--云计算概述(云计算是云原生的基础,IaaS、PaaS和SaaS服务模型)

1、云计算概念 云计算是一种通过互联网提供计算资源&#xff08;包括服务器、存储、数据库、网络、软件等&#xff09;和服务的技术模式。用户无需拥有和维护物理硬件&#xff0c;而是可以根据需要租用这些资源&#xff0c;并按使用量付费。 2、云计算特点 &#xff08;1&am…

一级滤波器设计:IL_cmdm > 80dB

目录 背景 目的 操作 仿真测试 搭建仿真模型 插入损耗测试 优化设计后重新测试 思考 背景 在选购共模电感时&#xff0c;规格书中通常会提供插损曲线或者阻抗-频率曲线&#xff0c;但这些数据都是在特定条件下测试获得的。如果将其集中在我们的样机中性能会如何&#…

qt 配置 mysql 驱动问题:Cannot load library qsqlmysql;QMYSQL driver not loaded

项目场景&#xff1a; 环境版本&#xff1a; qt &#xff1a;5.14.2 mysql&#xff1a;8.0 windows&#xff1a;10 提示&#xff1a;qt 配置 mysql 驱动&#xff1a; 项目场景&#xff1a;qt 配置 mysql 驱动 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a;…

Kubernetes相关的名词解释Container(16)

什么是Container&#xff1f; 在 Kubernetes 中&#xff0c;Container&#xff08;容器&#xff09; 是一个核心概念&#xff0c;你可以将镜像&#xff08;Image&#xff09;类比为程序的“源代码”&#xff0c;而容器是这段“代码”运行时的进程。例如&#xff0c;一个 nginx…

学习设计模式《四》——单例模式

一、基础概念 单例模式的本质【控制实例数目】&#xff1b; 单例模式的定义&#xff1a;是用来保证这个类在运行期间只会被创建一个类实例&#xff1b;单例模式还提供了一个全局唯一访问这个类实例的访问点&#xff08;即GetInstance方法&#xff09;单例模式只关心类实例的创建…

零基础上手Python数据分析 (19):Matplotlib 高级图表定制 - 精雕细琢,让你的图表脱颖而出!

写在前面 —— 超越默认样式,掌握 Matplotlib 精细控制,打造专业级可视化图表 上一篇博客,我们学习了 Matplotlib 的基础绘图功能,掌握了如何绘制常见的折线图、柱状图、散点图和饼图,并进行了基本的图表元素定制,例如添加标题、标签、图例等。 这些基础技能已经能让我…