C++子类访问父类成员

在 C++ 中,子类(派生类)访问父类(基类)的成员受到访问控制和*继承方式的约束。

1. 基类成员的访问说明符

基类中的成员可以声明为:

  • public :任何地方都能访问。

  • protected :类自身、派生类、友元可以访问。

  • private:仅类自身和友元可以访问,派生类**不能**直接访问。

2. 继承方式对成员访问级别的影响

继承方式(publicprotectedprivate)决定了基类成员在派生类中的访问级别

基类成员访问级别 public 继承 protected 继承 private 继承
public 变成 public 变成 protected 变成 private
protected 变成 protected 变成 protected 变成 private
private 不可访问 不可访问 不可访问
  • public 继承 :最常用,保持"is-a"关系。基类的 public 成员在派生类中仍是 publicprotected 仍是 protected

  • protected 继承 :基类 publicprotected 成员在派生类中都成为 protected

  • private 继承 :基类所有成员(除 private 外)在派生类中成为 private,用于实现"has-a"关系或组合。

3. 派生类访问基类成员的具体规则

无论采用何种继承方式,派生类**永远无法直接访问**基类的 `private` 成员。

派生类只能直接访问基类中 `public` 和 `protected` 的成员(但具体能否访问还受继承方式影响,如上表所示)。

示例:public 继承

cpp 复制代码
class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
};

class Derived : public Base {
public:
    void func() {
        pub = 10;   // OK:基类的 public 成员
        prot = 20;  // OK:基类的 protected 成员
        // priv = 30; // 错误:不能访问基类的 private 成员
    }
};
示例:protected 继承
cpp 复制代码
class Derived : protected Base {
public:
    void func() {
        pub = 10;   // OK:基类的 public 成员在派生类中变为 protected
        prot = 20;  // OK:基类的 protected 成员仍为 protected
        // priv = 30; // 错误:私有成员不可访问
    }
};

int main() {
    Derived d;
    // d.pub = 10; // 错误:在外部无法访问,因为 pub 在派生类中已是 protected
    return 0;
}
复制代码

4. 如何间接访问基类的私有成员?

派生类无法直接访问基类的私有成员,但可以通过基类提供的公有或受保护成员函数间接访问:

  • 公有成员函数 :基类提供 getter / setter 函数。

  • 受保护成员函数 :若基类希望派生类能够访问但又不想暴露给外部,可将函数声明为 protected

cpp 复制代码
class Base {
private:
    int secret;
public:
    Base(int s) : secret(s) {}
    int getSecret() const { return secret; }   // 公开接口
protected:
    void setSecret(int s) { secret = s; }      // 仅派生类可调用的修改接口
};

class Derived : public Base {
public:
    Derived(int s) : Base(s) {}
    void show() {
        std::cout << getSecret() << std::endl; // 通过公有函数访问
        setSecret(100);                        // 通过受保护函数修改
    }
};

5. 友元与继承

  • 如果基类将派生类声明为**友元**,则派生类可以直接访问基类的私有成员。但这种做法破坏了封装,通常不推荐。

  • 友元关系不能继承:基类的友元不会自动成为派生类的友元,反之亦然。

cpp 复制代码
class Base {
private:
    int secret;
    friend class Derived;   // 派生类成为基类的友元
};

class Derived : public Base {
public:
    void access() {
        secret = 10;   // OK:因为 Derived 是 Base 的友元
    }
};

6. 特殊情况:基类成员与派生类成员同名

当派生类定义了与基类同名的成员时,基类成员会被隐藏。如需访问基类成员,需使用作用域运算符 `::`:

cpp 复制代码
class Base {
public:
    int x;
};

class Derived : public Base {
public:
    int x;   // 隐藏了基类的 x
    void func() {
        x = 10;      // 访问派生类自己的 x
        Base::x = 20; // 访问基类的 x
    }
};

总结

  • 派生类只能直接访问 基类的 publicprotected 成员(具体能否访问还受继承方式影响)。

  • 基类的 private 成员永远不能 被派生类直接访问,但可通过基类提供的 public/protected 成员函数间接操作。

  • 选择合适的继承方式(通常为 public)来正确表达设计意图。

  • 使用 protected 成员来平衡封装性与派生类的访问需求。

相关推荐
不正经学生1 小时前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
毕竟是shy哥4 小时前
计算YOLO数据集中每个类的目标数
算法·yolo·机器学习
M78佐菲4 小时前
Linux学习笔记:TCP协议
linux·笔记·学习·tcp/ip·算法
恋恋西风4 小时前
C++ 理解 std::thread 在单核和多核上的行为差异
开发语言·c++
Brilliantwxx4 小时前
【Linux】 进程(9)程序与进程地址空间(基础+进阶+面试题)
linux·运维·服务器·开发语言·c++
BizzZ_5 小时前
C++(22)——类型转换和IO流
开发语言·c++
晊晌_h5 小时前
嵌入式从0到精通——数据结构总结[特殊字符]
数据结构·算法·排序算法
我找到地球的支点啦6 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
罗西的思考6 小时前
【OpenClaw具身硬件】ZeroClaw 源码阅读笔记(3)--- RAG
人工智能·算法·机器学习
浪里镖客7 小时前
位姿转换矩阵写法-个人习惯(计算机理解其实是相反的)
线性代数·算法·矩阵