C++成员访问权限以及继承权限

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的成员访问权限,如果类成员没有显式指定访问权限,则默认为公有权限。
posted @ 2026-02-04 16:28  thammer  阅读(8)  评论(0)    收藏  举报