c++函数名字隐藏

本文探讨了一个关于C++中名字隐藏的问题实例。通过一个具体的代码示例,展示了当派生类成员函数与基类虚拟函数同名时可能出现的编译错误,并给出了简单的解决方案。

昨晚在newsgroup上看到一个问题。我自己也弄错了。放在这。做个记录。

看下面的程序:

#include <iostream>
using namespace std;

class Base
{
public:
 virtual void fun(int a)
 {
  cout<< "Base fun"<<a <<endl;
 }
 virtual void fun()
 {
  cout<<"Base void fun" <<endl;
 }
};
class Der:public Base
{
public:
// using Base::fun;
 void fun()
 {
  cout<<"Der:: fun()" <<endl;
 }
};

void main()
{
 Der d;
 d.fun();
 d.fun(1);
}

有问题不? 咋一看一点问题都没有。但是编译器就是编译不了。呵呵。后来查到了说是个名字隐藏问题。解决方法很简单,把注释那行还原回来就ok了。

### C++ 中的名字隐藏机制 在 C++ 中,名字隐藏是一种重要的特性,它决定了派生类如何处理与基类同名的成员函数或变量。这种机制的核心在于编译器的行为以及作用域解析规则。 #### 名字隐藏的基本概念 当派生类定义了一个与其基类中已存在的名称相同的新实体时,无论该新实体是否具有不同的签名,都会发生 **名字隐藏**。这意味着派生类中的这个新实体会完全遮蔽掉基类中的同名实体[^4]。 #### 示例代码说明 以下通过一段示例程序来展示名字隐藏的现象: ```cpp #include <iostream> using namespace std; class Base { public: void show() { cout << "Base::show()" << endl; } }; class Derived : public Base { public: void show(int x) { cout << "Derived::show(" << x << ")" << endl; } }; int main() { Derived d; d.show(10); // 调用 Derived 的重载版本 d.Base::show(); // 显式调用 Base 的 show() } ``` 在这个例子中,`Derived` 类引入了 `void show(int)` 方法,这使得基类 `Base` 中的无参 `show()` 函数隐藏。如果尝试直接调用 `d.show()`(未指定参数),则会出现编译错误,因为派生类的方法已经屏蔽掉了基类的同名方法[^4]。 #### 解决方案:显式调用基类方法 为了能够继续访问被隐藏的基类方法,可以采用限定符的方式明确指出要调用的是哪个类的成员函数。例如,在上面的例子中我们使用了 `d.Base::show()` 来强制执行来自 `Base` 的实现[^4]。 另外一种更灵活的做法是在派生类内部利用 `using` 声明重新引入希望保留可见性的基类成员: ```cpp class Derived : public Base { public: using Base::show; // 将 Base::show 引入当前作用域 void show(int x) { cout << "Derived::show(" << x << ")" << endl; } }; ``` 这样即使存在多个重载形式也可以正常工作而不会互相干扰。 #### 关键点总结 - 如果派生类中有任何与基类同名的声明,则这些新的声明将会掩盖住原有那些可访问的内容。 - 使用 `using` 可以让特定基类成员再次变得可用而不受局部定义的影响。 - 对于虚函数而言,虽然它们可能看起来像是例外情况——实际上由于动态绑定的缘故允许越过某些层次去找到最终目标对象上的实际定义——但从严格意义上讲仍然属于覆盖而非单纯意义上的“隐藏”。 ### 进一步探讨虚拟继承下的名字查找规则 考虑到您提到过涉及虚拟继承的情况,这里补充一点相关内容。对于复杂的多重继承体系尤其是包含虚基类的情形下,C++ 提供了一套特别的设计用来确保共享状态的一致性和唯一性。具体到名字解析方面,即便某个共同祖先通过两条路径间接成为后代的一部分,只要遵循标准语法规则就能正确识别并定位所需资源[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值