当前位置: 首页 > news >正文

【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/


相关文章:

  • 深度学习-全连接神经网络
  • Kubernetes相关的名词解释Containerd(14)
  • YOLO11改进 | 特征融合Neck篇之Lowlevel Feature Alignment机制:多尺度检测的革新性突破
  • 模型检测技术的发展历史简介
  • 嵌入式开发板调试方式完全指南:串口/SSH/Telnet及其他方式对比
  • MySQL数据库 - InnoDB引擎
  • 详解.vscode 下的json .vscode文件夹下各个文件的作用
  • 基于SSM+Vue的社群交流市场服务平台【提供源码+论文1.5W字+答辩PPT+项目部署】
  • Java并发编程-线程通讯
  • 2025最新︱中国信通院静态应用程序安全测试(SAST)工具能力评估,悬镜安全灵脉AI通过评估!
  • 【刷题Day22】TCP(浅)
  • 【HCIA】简易的两个VLAN分别使用DHCP分配IP
  • Docker 集成KingBase
  • 【EasyPan】MySQL主键与索引核心作用解析
  • 助conda命令把环境导出为一个文件,然后在 Linux 系统里利用该文件重新创建相同的环境
  • 广东省大模型备案材料之测试题合格率判断标准
  • 【英语语法】词法---数词
  • 论文速报《CAL: 激光雷达中的零样本对象形状补全》
  • Deep Norm
  • spark–sql项目实验
  • 沈晓萍︱严金清:比斯坦因更早获得敦煌文物的无锡名士
  • 深交所修订创业板指数编制方案,引入ESG负面剔除机制
  • 刘国中:毫不松懈巩固拓展脱贫攻坚成果,全力以赴抓好农业防灾减灾工作
  • 许峰已任江苏省南京市副市长
  • 马上评丨别让“免费领养”套路坑消费者又坑宠物
  • 呼伦贝尔市委常委、组织部长闫轶圣调任内蒙古交通集团党委副书记