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 成员来平衡封装性与派生类的访问需求。

相关推荐
ShineWinsu1 小时前
对于Linux:模版方法类的解析以及socket、TcpSocket的封装
linux·c++·面试·socket·模板方法模式·封装·tcpsocket
稚南城才子,乌衣巷风流2 小时前
ST 表(Sparse Table)算法详解:原理、实现与应用
算法
hold?fish:palm2 小时前
9 找到字符串中所有字母异位词
c++·算法·leetcode
Sw1zzle3 小时前
算法入门(六):贪心算法 - 基础入门(Leetcode 121/455/860/376/738)
算法·leetcode·贪心算法
青山木3 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
不会就选b3 小时前
算法日常・每日刷题--<归并排序>1
数据结构·算法
危桥带雨4 小时前
排序算法(快排、归并、计数、基数排序)
数据结构·算法·排序算法
啦啦啦啦啦zzzz4 小时前
算法:回溯算法
c++·算法·leetcode
IT探索4 小时前
Linux 查找文件指令总结
linux·算法