C++子类访问父类成员

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

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

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

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

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

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

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

继承方式(public、protected、private)决定了基类成员在派生类中的访问级别:

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

  • protected 继承 :基类 public 和 protected 成员在派生类中都成为 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
    }
};

总结

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

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

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

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

相关推荐
启观川10 小时前
数据结构与算法 -第 3 章 常用算法-动态规划
数据结构·笔记·python·算法
码爸10 小时前
排序算法介绍
python·算法·排序算法
sm_9267870510 小时前
RFID 标签打印的技术实现要点与二次开发实践
java·大数据·前端·c++·编辑器
by2099910 小时前
C++ 多态:同一个基类接口,调用不同的函数
开发语言·c++·经验分享·多态
colinu11 小时前
C++ 异步任务与线程生命周期:`std::async`、`future`、`thread`、`jthread` 与协作式退出
java·jvm·c++
动词ing12 小时前
【题目练习】算法 组合总和||
算法
wuminyu12 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
longlongzihan12 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
专业程序开发源12 小时前
flask家电故障预测系统92491-计算机课程设计/毕业设计
vscode·python·sql·算法·flask·课程设计
liulilittle12 小时前
Linux 下 select 测试函数
linux·服务器·网络·数据库·c++·select·c