子类重载父类成员函数时父类的成员函数将隐藏

本文探讨了在面向对象编程中,子类继承父类时如何通过重载成员函数来隐藏父类中的同名函数,包括所有重载版本,并通过具体示例进行了说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承
重载父类中的成员函数将隐藏父类中该成员函数及其所有在父类中的重载函数。
例如:
class a
{
public:
    void a_func( void );
    void a_func( int);
};

class b : public a
{
public:
    void b_func( float );   //class中的a_func两个成员函数将都被隐藏(不能使用)。
    int b_func( void );      //同上。
}


 
<think>好的,我现在需要回答用户关于如何在C++中从子类调用父类成员函数的问题。用户已经提供了一些站内引用,我需要仔细分析这些引用中的信息,并结合自己的知识来给出准确且全面的回答。首先,用户提供的引用[1]中的代码示例展示了子类父类有同名成员变量和函数的情况。当子类覆盖了父类成员函数,可以通过作用域解析运算符`::`来显式调用父类的函数,比如`s1.Person::func()`。同,引用提到如果子类有与父类同名的函数,会隐藏父类的所有同名函数,包括重载版本,因此必须显式指定父类的作用域才能调用父类重载函数,如`s1.Person::func(100)`。 引用[2]讨论了子类内部和外部访问父类成员函数的权限问题。子类内部只能访问父类的protected和public成员,而无法访问private成员。在外部,子类对象的访问权限由继承方式决定,public继承下父类的public成员在子类中保持public,protected保持protected,private不可访问。因此,在外部调用,必须确保父类成员在子类中的访问权限是public,比如`b.h()`可以调用,而`b.g()`不行,因为g()在父类中是protected,继承后仍然是protected,无法在外部访问。 引用[3]的示例代码展示了通过域操作符调用父类虚函数的情况。即使子类重写了虚函数,仍然可以通过`b.A::func()`调用父类版本。这里需要注意的是,虚函数的多态性不影响显式调用父类函数的方式,只要使用作用域解析运算符即可。引用[4]提到当子类继承父类成员函数且未重写,该函数在代码段共享,子类可以直接调用。这说明如果函数未被覆盖,不需要特殊处理,直接调用即可,但需要注意访问权限。引用[5]详细讨论了函数重名的情况,无论是否使用virtual关键字,只要函数名相同,子类就会隐藏父类的同名函数。如果存在virtual关键字且参数相同,则形成多态,否则只是隐藏。此必须使用父类作用域来调用被隐藏的函数,否则会导致编译错误或无法调用。接下来,我需要整合这些信息,形成结构清晰的回答。首先,调用父类成员函数的几种方法,包括在子类内部和外部的情况,以及如何处理同名函数和访问权限的问题。然后,注意事项如隐藏规则、虚函数的影响等。最后生成相关问题。需要确保回答覆盖所有情况,比如显式作用域调用、虚函数的情况、访问权限的限制,以及内部和外部调用的区别。同,引用对应的示例和引用来源,如引用[1]、[3]等,来支持各个观点。注意使用正确的中文表达,避免技术术语错误,并保持逻辑连贯。</think>### C++子类调用父类成员函数的方法 #### 一、基本调用方式 1. **作用域解析运算符** 在子类外部或内部,通过`父类名::函数名`强制访问: ```cpp son s; s.Person::func(); // 调用父类非虚函数[^1] s.Person::func(100); // 调用父类重载函数[^1] ``` 2. **子类内部调用** 在子类成员函数中使用`父类名::`前缀: ```cpp void son::method() { Person::func(); // 调用父类版本[^2] } ``` #### 二、虚函数特殊处理 1. **多态调用** 使用基类指针/引用会自动调用实际对象类型的虚函数: ```cpp A* obj = new B(); obj->func(); // 调用B的虚函数[^3] obj->A::func(); // 强制调用A的虚函数[^3] ``` 2. **虚函数覆盖** 即使子类重写了虚函数,仍可通过基类名访问原实现: ```cpp b.B::func(); // 调用B的虚函数 b.A::func(); // 直接调用A的虚函数[^3] ``` #### 三、访问权限控制 1. **继承方式影响** - public继承:父类public保持public,protected保持protected - protected继承:父类public/protected变为protected - private继承:父类所有成员变为private 示例(public继承): ```cpp B b; b.h(); // 允许,父类public成员[^2] // b.g(); // 错误,protected成员[^2] ``` 2. **私有成员限制** 子类无法直接访问父类private成员函数: ```cpp class B : public A { void test() { // f(); // 错误,A::f()是private[^2] g(); // 允许,A::g()是protected[^2] } }; ``` #### 四、函数隐藏规则 1. **同名函数覆盖** 子类定义同名函数会隐藏父类所有同名函数: ```cpp son s; // s.func(100); // 错误,父类重载隐藏[^1] s.Person::func(100); // 必须显式指定[^1] ``` 2. **参数差异处理** 即使参数不同,同名函数仍会隐藏父类版本: ```cpp class Base { void func(int); }; class Derived : public Base { void func(string); }; Derived d; // d.func(10); // 错误,Base::func(int)被隐藏 d.Base::func(10); // 正确调用方式[^5] ``` #### 五、继承未重写函数 当子类未重写父类函数,直接继承函数代码段: ```cpp class Father { void print() { cout << "father"; } }; class Child : public Father {}; Child c; c.print(); // 输出"father",共享父类函数实现[^4] ``` ### 注意事项 1. **构造/析构顺序** 在构造函数中调用父类函数,需确保父类已完成初始化 2. **动态绑定限制** 通过作用域运算符调用的函数不触发动态绑定 3. **模板函数特殊处理** 父类模板函数需显式指定模板参数: ```cpp template<typename T> void Base::func(T param); Derived d; d.Base::func<int>(10); // 必须指定模板类型 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值