C++ 继承时的名字遮蔽问题

本文探讨了C++中派生类与基类同名成员函数如何造成遮蔽现象,以及如何通过基类作用域来访问被遮蔽的成员。基类和派生类的同名函数不构成重载,因为它们位于不同的作用域。在派生类作用域内,编译器只会找到派生类的同名函数,而忽略基类的。要调用基类的同名函数,必须使用基类作用域解析运算符。
摘要由CSDN通过智能技术生成

1、当派生类和基类的成员(包括成员函数和成员变量)同名时,派生类会遮蔽基类的成员。在派生类中使用该成员时实际上使用的是派生类中新增的成员,而不是从基类继承过来的。

2、基类的成员函数和派生类的成员函数不构成重载,成员的名字一样时会造成遮蔽。不管成员函数的参数如何,只要是名字一样就会造成遮蔽。

为什么基类和派生类同名的成员函数不构成重载呢?
 这是因为类其实也是一种作用域,当存在继承关系时,派生类的作用域是嵌套在基类的作用域之内的。编译器只会根据函数的名字来查找,不管参数是什么,如果一个同名的函数在派生类的作用域内没有找到那么再去基类的作用域中寻找。如果一个同名函数在派生类的作用域中找到了,不管有几个,那么编译器就不会再去外层的基类的作用域中寻找了。

编译器只会把派生类作用域中的同名函数作为一组候选函数,这一组候选函数会构成承载。也就是说,只有在同一作用域中的同名函数才会构成重载,不同作用域的同名函数会造成遮蔽。

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

class Base{
    public:
    void func();
    void func(int);
};
void Base::func() { std::cout << "Base::func()" << std::endl;}
void Base::func(int a) {std::cout << "Bsae::func(int)" << std::endl;}


class Derived: public Base{
    public:
    void func(const char *);
    void func(int, int);
};
void Derived::func(const char *str) { std::cout << "Derived::func(char *)" << std::endl;}
void Derived::func(int b, int c) { std::cout << "Derived::func(int, int)" << std::endl;}



int main(){
    Derived der;
    der.func("string"); 
    der.func(10, 20);

    // der.func(); // 编译错误,error: no matching function for call to ‘Derived::func()’
    // der.func(10); //编译错误, error: invalid conversion from ‘int’ to ‘const char*’
    
    der.Base::func(); //想要通过派生类访问被遮蔽的同名成员,必须要加上基类的作用域
    der.Base::func(10); //想要通过派生类访问被遮蔽的同名成员,必须要加上基类的作用域

    return 0;
}
    

输出结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值