继承体系中的隐藏机制解析(继承中的作用域)

发布于:2025-09-02 ⋅ 阅读:(23) ⋅ 点赞:(0)

目录

一、基本概念

二、成员变量隐藏示例

三、成员函数隐藏

重要提示:

四、总结说明

五、典型示例

六、相关选择题讲解

1、下面代码中的A和B类中的两个func构成什么关系()

知识回顾:函数签名(Function Signature)

2、下面程序的编译运行结果是什么()


一、基本概念

        在继承体系中,基类和派生类拥有各自独立的作用域。当派生类与基类中存在同名成员时,派生类成员会屏蔽对基类同名成员的直接访问,这种情况称为隐藏(Hide)或重定义(Redefinition)。


二、成员变量隐藏示例

以下代码展示了成员变量的隐藏现象:

#include <iostream>
#include <string>
using namespace std;

// 基类
class Person {
protected:
    int _num = 111;  // 身份编号
};

// 派生类
class Student : public Person {
public:
    void fun() {
        cout << _num << endl;  // 访问的是Student类的_num
    }
protected:
    int _num = 999;  // 学号
};

int main() {
    Student s;
    s.fun();  // 输出:999
    return 0;
}

若要访问基类中的同名成员,需使用作用域限定符::)显式指定:

void fun() {
    cout << Person::_num << endl;  // 输出:111(访问基类的_num)
}


三、成员函数隐藏

成员函数的隐藏只需函数名相同即可构成,与参数列表无关:

        例如,对于以下代码,调用成员函数fun时将直接调用子类当中的fun,若想调用父类当中的fun,则需使用作用域限定符指定类域。

#include <iostream>
#include <string>
using namespace std;

// 基类
class Person {
public:
    void fun(int x) {
        cout << x << endl;
    }
};

// 派生类
class Student : public Person {
public:
    void fun(double x) {  // 与基类fun函数构成隐藏
        cout << x << endl;
    }
};

int main() {
    Student s;
    s.fun(3.14);           // 调用Student::fun(double)
    s.Person::fun(20);     // 调用Person::fun(int)
    return 0;
}

重要提示

        基类与派生类中的fun函数不构成函数重载,因为函数重载要求在同一作用域内。为避免混淆,在继承体系中应尽量避免定义同名成员。


四、总结说明

  1. 继承体系中基类和派生类拥有独立作用域

  2. 派生类与基类同名成员构成隐藏关系,派生类成员屏蔽基类成员的直接访问

  3. 可使用基类::基类成员语法显式访问被隐藏的基类成员

  4. 成员函数只需函数名相同即构成隐藏,与参数类型和数量无关

  5. 实际开发中应尽量避免在继承体系中定义同名成员


五、典型示例

#include <iostream>
#include <string>
using namespace std;

class Person {
protected:
    string _name = "小李";
    int _num = 111;  // 身份证号
};

class Student : public Person {
public:
    void Print() {
        cout << "姓名:" << _name << endl;
        cout << "身份证号:" << Person::_num << endl;  // 显式访问基类成员
        cout << "学号:" << _num << endl;              // 访问派生类成员
    }
protected:
    int _num = 999;  // 学号(与基类_num构成隐藏)
};

int main() {
    Student s1;
    s1.Print();
    return 0;
}


六、相关选择题讲解

1、下面代码中的A和B类中的两个func构成什么关系()

答案:B.隐藏

解析:虽然函数签名不同,但因处于不同作用域且函数名相同,构成隐藏关系而非重载。

知识回顾:函数签名(Function Signature)

函数签名是编译器用于区分不同函数的一个唯一标识。它主要由以下部分组成:

  1. 函数名

  2. 参数列表(参数的类型数量顺序

特别注意:函数的返回类型不属于函数签名的一部分。

2、下面程序的编译运行结果是什么()

答案:A.编译报错

解析:b.fun()调用会产生编译错误,因为派生类的fun(int)隐藏了基类的fun(),而b.fun()找不到无参版本。需要使b.A::fun()显式调用基类函数。

class A {
public:
    void fun() {
        cout << "func()" << endl;
    }
};

class B : public A {
public:
    void fun(int i) {  // 隐藏了A::fun()
        cout << "func(int i)" << i << endl;
    }
};

int main() {
    B b;
    b.fun(10);     // 正确:调用B::fun(int)
    b.fun();    // 错误:A::fun()被隐藏
    b.A::fun();    // 正确:显式调用基类函数
    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到