C++继承中的名称遮掩
摘自《effective C++ 3rd>
考虑下列代码:
class base { private: std::string s; public: base():s("base") { } void p() { std::cout<< s <<std::endl; } void p(int a) { std::cout<< a<<std::endl; } }; class derive : public base { private: std::string s; public: derive():s("derive") { } void p() { std::cout<<s<<std::endl; } }; int main() { derive d; d.p();//print derive d.p(2);//error base* bptr = &d;
bptr->p(2); //ok
}
上面的代码展示了,derive类“没有能够成功继承”base中的void p(int)函数。打上引号的原因是,我们使用基类指针指向派生类时,又能够成功调用。
从名称查找的观点出发,base::p(int)被derive::p()函数遮蔽了。
编译器拒绝这样的继承是为了防止在程序库或应用框架内建立新的derived class 时附带地从疏远的base classes 继承重载函数。
通过在derive类中声明可以显示base函数的名称:
class derive
{
using base::p;
...//same code
}
derived classes 内的名称会遮掩base classes 内的名称。
这意味着如果继承base class并加上重载函数,而又希望在derive中重新定义或覆写其中一部分,那必须手动使用using 声明那些覆写的函数,夫走某些希望继承的名称会被遮掩。