TUTORIAL编程语言与算法FETCHED

C++ 类访问修饰符

C++ 类访问修饰符 C++ 类 & 对象 在 C++ 面向对象编程(OOP)中,数据封装(Encapsulation) 是核心概念之一。简单来说,就是把数据“藏”起来,只开放必要的接口给外界使用,以保证数据的安全。 为了控制谁能看到这些数据,C++ 提供了三个关键字,称为访问修饰符: public (公有) private (私有) protected (受保护) [mycode3 ty..

更新于 2026/7/16

教程详情页默认 noindex。

C++ 类访问修饰符

C++ 类 & 对象 C++ 类 & 对象

在 C++ 面向对象编程(OOP)中,数据封装(Encapsulation) 是核心概念之一。简单来说,就是把数据"藏"起来,只开放必要的接口给外界使用,以保证数据的安全。

为了控制谁能看到这些数据,C++ 提供了三个关键字,称为访问修饰符:

  • public (公有)
  • private (私有)
  • protected (受保护)
class Base { public: //公有成员 protected: // 受保护成员 private: // 私有成员 };

为了方便理解,我们可以把一个类(Class)想象成你的家:

修饰符 现实类比 谁可以访问? 典型用途
public 客厅/大门 所有人(类内部、子类、外部代码) 对外提供的接口函数(API)。
protected 卧室 你和你的孩子(类内部、子类) 仅限家族内部(继承体系)使用的数据。
private 保险箱 只有你自己(仅限本类内部) 核心数据、不想被随意修改的变量。

注意:如果不写任何修饰符,C++ 类成员默认是 private(私有) 的。

公有(public)成员

公有成员在程序中任何地方都能访问,无需通过成员函数读写,示例如下:

实例

#include <iostream> using namespace std; class Line { public: double length; void setLength( double len ); double getLength( void ); }; // 成员函数定义 double Line::getLength(void) { return length ; } void Line::setLength( double len ) { length = len; } // 程序的主函数 int main( ) { Line line; // 设置长度 line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; // 不使用成员函数设置长度 line.length = 10.0; // OK: 因为 length 是公有的 cout << "Length of line : " << line.length <<endl; return 0; }

当上面的代码被编译和执行时,它会产生下列结果:

Length of line : 6
Length of line : 10

私有(private)成员

私有成员对类外完全封闭,外部代码无法读取、修改或调用,派生类同样无权直接访问。只有类自身的成员函数与被授予友元权限的实体能够操作这些内容。

类中若未使用任何访问说明符,成员默认为私有。如下例所示,width 自动落入私有区域,表明未明确标注的成员均按私有处理:

实例

class Box { double width; public: double length; void setWidth( double wid ); double getWidth( void ); };

实际操作中,我们一般会在私有区域定义数据,在公有区域定义相关的函数,以便在类的外部也可以调用这些函数,如下所示:

实例

#include <iostream> using namespace std; class Box { public: double length; void setWidth( double wid ); double getWidth( void ); private: double width; }; // 成员函数定义 double Box::getWidth(void) { return width ; } void Box::setWidth( double wid ) { width = wid; } // 程序的主函数 int main( ) { Box box; // 不使用成员函数设置长度 box.length = 10.0; // OK: 因为 length 是公有的 cout << "Length of box : " << box.length <<endl; // 不使用成员函数设置宽度 // box.width = 10.0; // Error: 因为 width 是私有的 box.setWidth(10.0); // 使用成员函数设置宽度 cout << "Width of box : " << box.getWidth() <<endl; return 0; }

当上面的代码被编译和执行时,它会产生下列结果:

Length of box : 10
Width of box : 10

protected(受保护)成员

protected 的存在主要是为了继承。

  • 如果没有继承,它和 private 一样(外人不可见)。
  • 如果有继承,子类(派生类)可以访问父类的 protected 成员,但不能访问 private 成员。

在下一个章节中,您将学习到派生类和继承的知识。现在您可以看到下面的实例中,我们从父类 Box 派生了一个子类 smallBox。

下面的实例与前面的实例类似,在这里 width 成员可被派生类 smallBox 的任何成员函数访问。

实例

#include <iostream> using namespace std; class Box { protected: double width; }; class SmallBox:Box // SmallBox 是派生类 { public: void setSmallWidth( double wid ); double getSmallWidth( void ); }; // 子类的成员函数 double SmallBox::getSmallWidth(void) { return width ; } void SmallBox::setSmallWidth( double wid ) { width = wid; } // 程序的主函数 int main( ) { SmallBox box; // 使用成员函数设置宽度 box.setSmallWidth(5.0); cout << "Width of box : "<< box.getSmallWidth() << endl; return 0; }

当上面的代码被编译和执行时,它会产生下列结果:

Width of box : 5

继承中的访问权限变化

当你定义一个子类时(如 class B : public A),冒号后面的 public 也是一种访问修饰符,它决定了父类的成员在子类中"表现"成什么样。

这看起来很复杂,但只需要记住这个降级原则:

继承方式决定了父类成员在子类中的最高权限。
如果继承方式比成员原本的权限更严格,成员的权限就会被"降级"到继承方式的级别。

权限变化表

父类成员原权限 public 继承 (最常用) protected 继承 private 继承
public 保持 public 降级为 protected 降级为 private
protected 保持 protected 保持 protected 降级为 private
private 不可访问 不可访问 不可访问

注:不可访问指子类代码无法直接使用该变量,但变量依然存在于内存中。

综合演示代码

为了清晰展示,我们将变量重命名为 pub_var (公有), pro_var (受保护), pri_var (私有)。

实例

#include <iostream>
using namespace std;

class Parent {
public:
    int pub_var;
protected:
    int pro_var;
private:
    int pri_var; // 只有 Parent 自己能动

public:
    Parent() { pub_var = 1; pro_var = 2; pri_var = 3; }
};

// 1. 公有继承(Public Inheritance)- 最常见,原汁原味
class ChildA : public Parent {
public:
    void test() {
        cout << pub_var << endl; // OK
        cout << pro_var << endl; // OK
        // cout << pri_var << endl; // 错误!父类私有成员不可见
    }
};

// 2. 受保护继承(Protected Inheritance)- 大家都变成了受保护
class ChildB : protected Parent {
public:
    void test() {
        cout << pub_var << endl; // OK,但在 ChildB 看来,它是 protected
        cout << pro_var << endl; // OK
    }
};

// 3. 私有继承(Private Inheritance)- 大家都变成了私有
class ChildC : private Parent {
public:
    void test() {
        cout << pub_var << endl; // OK,但在 ChildC 看来,它是 private
        cout << pro_var << endl; // OK,但在 ChildC 看来,它是 private
    }
};

int main() {
    ChildA a;
    cout << a.pub_var << endl; // OK,外部可以访问
    // cout << a.pro_var << endl; // 错误,外部不可访问 protected

    ChildB b;
    // cout << b.pub_var << endl; // 错误!因为是 protected 继承,pub_var 在外部变成了 protected

    ChildC c;
    // cout << c.pub_var << endl; // 错误!因为是 private 继承,pub_var 在外部变成了 private

    return 0;
}

总结

  • Public: 谁都能用。做接口(API)用。
  • Private: 只有自己能用。存数据用(默认安全选项)。
  • Protected: 只有家族(继承链)能用。给子类留后门用。

继承:

  • Public 继承:父类的属性保持不变(最常用)。
  • Private/Protected 继承:会收紧父类成员的权限,通常用于特殊的实现场景。

C++ 类 & 对象 C++ 类 & 对象