一个示例简要说明name hiding

正常来说子类包含父类的一切,对,就是一切。
但是,当子类有父类的同名函数时会出现name hiding现象,即子类无法调用父类的同名函数,仿佛子类里根本没继承到一样。注意这里的同名函数时不带关键字virtual的,即非虚函数。

跟override一起看更容易弄懂

test_namehiding.h

#pragma once
#include <iostream>

class BaseA{
public:
    BaseA(int i) : i_(i){std::cout << "BaseA::BaseA()" << std::endl;}
    ~BaseA() {std::cout << "BaseA::~BaseA()" << std::endl;} 

    void printVal();
    void printVal(std::string msg);
    
    void setVal(int i){
        i_ = i;
    }
    
    int getVal(){
        return i_;
    }
    
private:
    int i_;
};

class DerivedA: public BaseA
{
public:
    DerivedA(int i): BaseA(i){std::cout << "DerivedA::DerivedA()" << std::endl;}
    ~DerivedA(){std::cout << "DerivedA::~DerivedA()" << std::endl;}
    void printVal();
    int printVal(int ct);
private:
};

test_namehiding.cpp

#include "test_namehiding.h"
#include <iostream>

void BaseA::printVal()
{
    std::cout << "BaseA::i_=" << i_ << std::endl;
}

void BaseA::printVal(std::string msg)
{
    std::cout << "BaseA::msg: " << msg << ", ";
    printVal();
}
    
void DerivedA::printVal()
{
    std::cout << "DerivedA::i_=" << BaseA::getVal() << std::endl;
    
    // 直觉上子类应该继承父类的两个overload的printVal方法,但是实际上并没有,所以下面两句都错
    //std::cout << BaseA::printVal("BaseA::msg") << std::endl;  // 子类企图调用父类的方法, error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'void') ,后面还有一大串错误

    //std::cout << BaseA::printVal() << std::endl;  // 子类企图调用父类的方法, error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'void'),后面还有一大串错误
}

int DerivedA::printVal(int ct)
{
    std::cout << "Parameter is: " << ct << std::endl;

    // 子类printVal的参数、返回值和父类的不一样也不行,也就是说只要子类的非虚函数的函数名和父类的一样,父类的方法在子类中就不见了,即出现所谓的name hiding
    std::cout << BaseA::printVal() << std::endl; //  子类企图调用父类的方法, error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'void')
}

main.cpp

/*
    JetBrains/CLion 2022.1/bin/mingw/bin/g++
    g++.exe (GCC) 11.2.0
 */
#include "test_namehiding.h"
#include <iostream>

int main()
{
    BaseA a(0);
    a.printVal();
    a.setVal(100);
    a.printVal("message");
    
    std::cout << "-------------------------------\n";
    
    DerivedA b(9);
    b.printVal();
    // b.printVal("DerivedA's message");  // 企图调用父类的方法, [ERROR] error: no matching function for call to 'DerivedA::printVal(const char [19])'
    //b.printVal(25);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值