C++ 类封装与访问权限详解:从原理到代码实战

洛溪
洛溪
发布时间:2026-10-16 | 6人浏览过
原创

C++ 通过类(Class)或结构体(Struct)实现封装,利用 public 和 private 关键字控制成员的访问权限,从而分离使用方式与内部实现细节。本文结合继承案例与代码示例,详细解析封装的原理、访问级别差异以及成员变量的作用域规则。

一、类的基本概念与组合

理解类之前,先观察现实世界中的复杂对象。例如一台电脑由 CPU、内存、主板、键盘和硬盘等多个部件组合而成。在面向对象设计中,这种将多个独立单元结合成一个整体对象的方式称为类的组合。

二、类的封装机制

类通常包含两个层面的信息:
1. 类的实现细节(内部逻辑、数据结构等)。
2. 类的使用方式(对外提供的接口、功能)。

封装的核心目的是实现使用与实现的分离:
- 使用者无需关心类的内部如何实现,只需知道如何调用即可。
- 创建者需要考虑内部的实现细节,并对暴露给外界的接口进行保护。

直观类比:手机用户与工程师

  • 普通用户:只需要学习如何使用手机的功能,如发短信、打电话、拍照等,无需了解内部电路原理。
  • 开发工程师:需要深入研究手机内部的硬件连接、系统架构等实现细节。

C++ 中的访问控制

在编程中,并非所有属性都适合对外公开。例如个人隐私(体重、年龄、收入)不应被随意访问,而公共信息(姓名、学历)则可以公开。C++ 通过访问级别来控制数据的可见性,这与操作系统的文件权限类似。

关键术语

  • 成员变量:表示类的属性。
  • 成员函数:表示类的行为。
  • public(公有):成员变量和函数可以在类内部和外部被访问和调用。
  • private(私有):成员变量和函数只能在类的内部被访问和调用,外部无法直接访问。

代码实战:性别角色与权限控制

下面通过一个具体的继承案例来演示 public 和 private 的实际效果。本例定义了 Biology(生物)、Animal(动物)、Human(人类),并派生出 Girl 和 Boy。

#include <stdio.h>
 
struct Biology 
{
    bool living;
};
 
struct Animal : Biology 
{
    bool movable;
    
    void findFood()
    { 
    }
};
 
 
struct Human : Animal 
{
    void sleep() 
    { 
        printf("I'm sleeping...\n");
    }
    
    void work() 
    { 
        printf("I'm working...\n");
    }
};
 
struct Girl : Human
{
private:
    int age;
    int weight;
public:
    void print()
    {
        age = 22;
        weight = 48;
        
        printf("I'm a girl, I'm %d years old.\n", age);
        printf("My weight is %d kg.\n", weight);
    }
};
 
struct Boy : Human
{
private:
    int height;
    int salary;
public:
    int age;
    int weight;
 
    void print()
    {
        height = 175;
        salary = 9000;
        
        printf("I'm a boy, my height is %d cm.\n", height);
        printf("My salary is %d RMB.\n", salary);
    }    
};
 
int main()
{
    Girl g;
    Boy b;
    
    g.print();
    
    b.age = 19;
    b.weight = 120;
    //b.height = 180; // 这将导致编译错误
    
    b.print();
    
    return 0;
}

上述代码运行后的输出结果如下:

关键点分析

在 Girl 结构中,age 和 weight 被标记为 private,因此只能在 print() 方法内部被修改和使用,外部无法直接访问。而在 Boy 结构中,height 和 salary 是私有的,但 age 和 weight 保留为默认的公有状态(因为在 struct 中未指定访问级别默认为 public,且在 private 块之后重新声明的未标记成员默认遵循上一级或默认为 public,此处需注意 C++ struct 默认 public 的特性,具体见下方作用域章节)。

如果我们尝试在外部访问 Boy 中的私有成员 height:

b.height = 180;

编译器会报错,因为 private 成员禁止在类外部直接访问:

三、类成员的作用域

作用域(Scope)决定了标识符在程序中的可见范围。虽然访问权限控制的是“能否访问”,但作用域控制的是“是否可见”。两者虽有区别但在实际使用中紧密相关。

作用域规则

  • 类内部可见性:所有类成员(无论 public 还是 private)在类内部都是可见且可访问的。
  • 成员函数互访:成员函数可以直接访问同类的其他成员变量和调用其他成员函数。
  • 外部访问限制:类的外部只能通过对象访问 public 成员,无法直接访问 private 成员。
  • 注意:在 C++ 中使用 struct 定义的类中,如果未显式指定访问级别,所有成员默认均为 public;而使用 class 时默认成员为 private。本例代码使用 struct 并在部分位置显式使用了 private 关键字,请以代码中的显式声明为准。

作用域示例代码

以下代码演示了局部变量、全局变量和类成员变量之间的命名冲突与作用域区分:

#include <stdio.h>
 
int i = 1; // 全局变量
 
struct Test
{
private:
    int i; // 类内私有成员变量,遮蔽全局变量i
 
public:
    int j; // 类内公有成员变量
        
    int getI()
    {
        i = 3; // 此处访问的是类内私有变量 i
        
        return i;
    }
};
 
int main()
{
    int i = 2; // 局部变量
    
    Test test;
    
    test.j = 4;
    
    printf("i = %d\n", i);              // 输出: i = 2 (局部变量)
    printf("::i = %d\n", ::i);          // 输出: ::i = 1 (全局变量,使用作用域解析运算符)
    // printf("test.i = %d\n", test.i);    // 错误:test.i 是 private,外部不可访问
    printf("test.j = %d\n", test.j);    // 输出: test.j = 4 (公有成员)
    printf("test.getI() = %d\n", test.getI()); // 输出: test.getI() = 3 (通过公有方法访问私有成员)
    
    return 0;
}

运行结果:

:: 是作用域解析运算符,用于访问全局命名空间中的变量。当局部变量或成员变量与全局变量同名时,直接使用名称会优先匹配最近的作用域,此时需要使用 :: 明确指向全局变量。

四、小结

  • 封装的本质:将类分为“使用方式”和“内部细节”两部分,通过封装使二者分离,降低耦合。
  • 访问控制:C++ 通过 public 和 private 定义成员的可见性。public 允许内外访问,private 仅限类内访问。
  • 作用域隔离:类成员的作用域独立于外部,即使名称相同也不会产生混淆,外部必须通过公有接口或直接公有成员进行操作。
  • 最佳实践:建议将数据成员设置为 private,并提供公有的 getter/setter 方法进行受控访问,以保证数据的安全性。

以上就是 C++ 类与封装概念的详细内容,更多关于 C++ 类的设计原则与访问控制技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表