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;
}
输出结果: