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