惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
G
Google Developers Blog
MyScale Blog
MyScale Blog
Google DeepMind News
Google DeepMind News
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Check Point Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed
D
Docker
Jina AI
Jina AI
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
Google DeepMind News
Google DeepMind News
L
LINUX DO - 最新话题
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
MongoDB | Blog
MongoDB | Blog
Attack and Defense Labs
Attack and Defense Labs
Webroot Blog
Webroot Blog
A
About on SuperTechFans
Schneier on Security
Schneier on Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Azure Blog
Microsoft Azure Blog
F
Fortinet All Blogs
IT之家
IT之家
The Last Watchdog
The Last Watchdog
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog
Project Zero
Project Zero
B
Blog
Recorded Future
Recorded Future
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
SegmentFault 最新的问题
Security Archives - TechRepublic
Security Archives - TechRepublic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
T
Threatpost
H
Heimdal Security Blog
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog

博客园 - thammer

03 — std::vector 进阶篇 02 — 迭代器基础 01 — std::vector 基础篇 Day 17:Promise 基础 Day 16 - 读懂 TypeScript 声明文件(.d.ts) Day 15 - ArkTS 模块系统 Day 14 - ArkTS 错误处理 Day 13 - ArkTS 类型系统进阶 Day 12 - 泛型与阶段三总结 Day 11 - Interface 与类型契约 Day 10 - 继承与多态 Day 09 - Class 基础 Day 08 - 函数进阶与阶段总结 Day 07 - 函数类型与高阶函数 Day 06 - 函数基础 Day 05 - 数组和元组深入 Day 04 - 循环与迭代 Day 03 - 条件控制 Day 02 - 运算符与表达式 Day 01 - 变量与类型基础 Day 00 - 环境准备 C++虚函数 C++ 多继承 C++ 成员初始化机制总结笔记
C++成员访问权限以及继承权限
thammer · 2026-02-04 · via 博客园 - thammer

C++中访问控制权限有三种:public, private, protected。它们的作用分为两类:

  1. 自身成员访问权限控制
    用法:
    限定关键字:成员声明
    
  2. 基类继承成员访问权限控制
    用法:
    限定关键字 基类
    

自身成员访问权限控制

在类/结构体或者联合体的成员声明序列中,它的主要作用是定义后续成员的可访问权限。例如:

class A {
public:
    int a;
private:
    int b;
protected:
    int c;
};

struct B {
public:
    int a;
private:
    int b;
protected:
    int c;
};

union C {
public:    
    int a;
private:
    int b;
protected:
    int c;
};

这里的成员包括:成员函数、成员变量、成员类型,并且不受静态、非静态限定的影响。

class A
{
public:
    //成员函数
    void foo(){ }
    
    //成员变量
    int a;
    
    //成员类型
    enum AEnum
    {
        AE_1,
        AE_2,
    };
};

对成员的访问权限的控制,是站在类自身与访问对象的继承关系的视角来看的。

  • public:本类内部、派生类、以及类外部都可以访问
  • protected:本类内部和派生类可以访问,类外部不能访问
  • private:只有本类内部可以访问
class A
{
public:
    // 成员函数(不管这个成员函数自身是哪种访问权限),不受访问权限限制(都是自己的部件,想怎么样就怎么样)
    void foo()
    {
        a = 1;
        b = 2;
        c = 3;
    }

public:
    int a;

protected:
    int b;

private:
    int c;
};

class B : public A
{
public:
    // "is a" 关系,继承A类,子类可以访问基类public和protected成员,不能访问基类private成员
    void bar()
    {
        a = 1;
        b = 2;
        // c = 3; 公有继承,子类不能访问基类private成员
    }
};

class C
{
public:
    // "has a" 关系,包含一个A类的对象,但是不是继承关系,仅能访问public限定的成员
    void tar()
    {
        a.a = 1;
        // a.b = 2; // 非成员函数不能访问保护成员
        // a.c = 3; // 非成员函数不能访问私有成员
    }

private:
    A a;
};

void zar()
{
    A a;
    a.a = 1;
    // a.b = 2; // 非成员函数不能访问保护成员
    // a.c = 3; // 非成员函数不能访问私有成员
}

基类继承成员访问权限控制

在派生类的声明中,修饰派生类对基类的继承方式。具体指什么呢?就是指修饰派生类继承基类的成员访问权限。如下面的例子:

public继承

class Base
{
public:
    int a;

protected:
    int b;

private:
    int c;
};

class Derived : public Base
{
public:
    void accessBaseMember()
    {
        a = 1; // 基类public权限维持为派生类public权限访问
        b = 2; // 基类protected权限维持为派生类protected权限访问
        // c = 3; 基类private权限,无权限访问
    }
};

void foo()
{
    Derived d;
    d.a = 1; // 基类public权限维持为派生类public权限,非成员函数可以访问
    // d.b = 2; 基类protected权限维持为派生类protected权限, 非成员函数无权限访问
    // d.c = 3; 基类private权限,非成员函数无权限访问
}

protected继承

class Base
{
public:
    int a;

protected:
    int b;

private:
    int c;
};

class Derived : protected Base
{
public:
    void accessBaseMember()
    {
        a = 1; // 基类public权限降级为派生类protected权限访问
        b = 2; // 基类protected权限维持为派生类protected权限访问
        // c = 3; 基类private权限,无权限访问
    }
};

void foo()
{
    Derived d;
    // d.a = 1; 基类public权限降级为派生类protected权限,非成员函数无权限访问
    // d.b = 2; 基类protected权限维持为派生类protected权限, 非成员函数无权限访问
    // d.c = 3; 基类private权限,非成员函数无权限访问
}

private继承

class Base
{
public:
    int a;

protected:
    int b;

private:
    int c;
};

class Derived : private Base
{
public:
    void accessBaseMember()
    {
        a = 1; // 基类public权限降级为派生类private权限访问
        b = 2; // 基类protected权限维持为派生类private权限访问
        // c = 3; 基类private权限,无权限访问
    }
};

void foo()
{
    Derived d;
    // d.a = 1; 基类public权限降级为派生类private权限,非成员函数无权限访问
    // d.b = 2; 基类protected权限维持为派生类private权限, 非成员函数无权限访问
    // d.c = 3; 基类private权限,非成员函数无权限访问
}

通过上面的3种继承权限,可以看出,规则是:

  • 共有继承:在访问说明符后列出的基类的公有成员和受保护成员,在派生类中保持其原有的成员访问权限。
  • 保护继承:访问说明符后列出的基类的公有成员和保护成员将成为派生类的保护成员。
  • 私有继承:访问说明符后列出的基类的公开和受保护成员将成为派生类的私有成员。
  • 基类的私有成员:始终对派生类不可访问,无论采用公有、受保护还是私有继承方式。

默认继承权限

  • 如果类成员没有显式指定访问权限,则默认为私有权限。
  • 如果派生类没有显式指定继承权限,则默认为私有继承。
  • 为了兼容C的struct的成员访问权限,如果类成员没有显式指定访问权限,则默认为公有权限。