菜鸟教程 -- 学的不仅是技术,更是梦想!

C++ 教程
C++ 教程 C++ 简介 C++ 环境设置 C++ 基本语法 C++ 注释 C++ 数据类型 C++ 变量类型 C++ 变量作用域 C++ 常量 C++ 修饰符类型 C++ 存储类 C++ 运算符 C++ 循环 C++ 判断 C++ 函数 C++ 数字 C++ 数组 C++ 字符串 C++ 指针 C++ 引用 C++ 日期 & 时间 C++ 基本的输入输出 C++ 结构体(struct) C++ vector 容器 C++ 数据结构

C++ 面向对象

C++ 类 & 对象 C++ 继承 C++ 重载运算符和重载函数 C++ 多态 C++ 数据抽象 C++ 数据封装 C++ 接口(抽象类)

C++ 高级教程

C++ 文件和流 C++ 异常处理 C++ 动态内存 C++ 命名空间 C++ 模板 C++ 预处理器 C++ 信号处理 C++ 多线程 C++ Web 编程

C++ 资源库

C++ STL 教程 C++ 导入标准库 C++ 标准库 C++ 有用的资源 C++ 实例 C++ 测验 C++ <iostream> C++ <fstream> C++ <sstream> C++ <iomanip> C++ <array> C++ <vector> C++ <list> C++ <forward_list> C++ <deque> C++ <stack> C++ <queue> C++ <priority_queue> C++ <set> C++ <unordered_set> C++ <map> C++ <unordered_map> C++ <bitset> C++ <algorithm> C++ <iterator> C++ <functional> C++ <numeric> C++ <complex> C++ <valarray> C++ <cmath> C++ <string> C++ <regex> C++ <ctime> C++ <chrono> C++ <thread> C++ <mutex> C++ <condition_variable> C++ <future> C++ <atomic> C++ <type_traits> C++ <typeinfo> C++ <exception> C++ <stdexcept> C++ <cstdio> C++ <cstdint> C++ <memory> C++ <new> C++ <utility> C++ <random> C++ <locale> C++ <codecvt> C++ <cassert> C++ <cwchar> C++ <climits> C++ <cfloat> C++ <cstdlib> C++ <numbers> C++ OpenCV
(追記) (追記ここまで)

C++ 类访问修饰符

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

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

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

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

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

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

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

公有(public)成员

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

实例

#include<iostream>usingnamespacestd; classLine{public: doublelength; voidsetLength(doublelen); doublegetLength(void); }; // 成员函数定义doubleLine::getLength(void){returnlength ; }voidLine::setLength(doublelen){length = len; }// 程序的主函数intmain(){Lineline; // 设置长度line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; // 不使用成员函数设置长度line.length = 10.0; // OK: 因为 length 是公有的cout << "Length of line : " << line.length <<endl; return0; }

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

Length of line : 6
Length of line : 10

私有(private)成员

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

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

实例

classBox{doublewidth; public: doublelength; voidsetWidth(doublewid); doublegetWidth(void); };

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

实例

#include<iostream>usingnamespacestd; classBox{public: doublelength; voidsetWidth(doublewid); doublegetWidth(void); private: doublewidth; }; // 成员函数定义doubleBox::getWidth(void){returnwidth ; }voidBox::setWidth(doublewid){width = wid; }// 程序的主函数intmain(){Boxbox; // 不使用成员函数设置长度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; return0; }

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

Length of box : 10
Width of box : 10

protected(受保护)成员

protected 的存在主要是为了继承

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

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

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

实例

#include<iostream>usingnamespacestd; classBox{protected: doublewidth; }; classSmallBox:Box// SmallBox 是派生类{public: voidsetSmallWidth(doublewid); doublegetSmallWidth(void); }; // 子类的成员函数doubleSmallBox::getSmallWidth(void){returnwidth ; }voidSmallBox::setSmallWidth(doublewid){width = wid; }// 程序的主函数intmain(){SmallBoxbox; // 使用成员函数设置宽度box.setSmallWidth(5.0); cout << "Width of box : "<< box.getSmallWidth() << endl; return0; }

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

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++ 类 & 对象

AI 思考中...

2 篇笔记 写笔记

  1. #0

    narip

    nar***[email protected]

    413

    在类里面不写是什么类型,默认是 private 的。

    include <iostream>
    using namespace std;
    class Line{
     int a;
    };
    int main() {
     Line line;
     line.a = 5;
     cout<<line.a<<endl;
    }

    这个是会报错的,应该改成:

    class Line{
     public:
     int a;
    };

    narip

    nar***[email protected]

    9年前 (2017年10月26日)
  2. #0

    Bad_Boy

    tia***[email protected]

    644

    如果继承时不显示声明是 private,protected,public 继承,则默认是 private 继承,在 struct 中默认 public 继承:

    class B : A {};
    B b;
    b.a; //错误
    b.a1; //错误
    b.a2; //错误
    b.a3; //错误

    总结一下三种继承方式:

    继承方式 基类的public成员 基类的protected成员 基类的private成员 继承引起的访问控制关系变化概括
    public继承 仍为public成员 仍为protected成员 不可见 基类的非私有成员在子类的访问属性不变
    protected继承 变为protected成员 变为protected成员 不可见 基类的非私有成员都为子类的保护成员
    private继承 变为private成员 变为private成员 不可见 基类中的非私有成员都称为子类的私有成员

    Bad_Boy

    tia***[email protected]

    8年前 (2018年09月25日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /