目 录CONTENT

文章目录

C++ 函数隐藏(Function Hiding)

TalentQ
2025-09-13 / 0 评论 / 0 点赞 / 3 阅读 / 0 字

1 概念

函数隐藏指的是派生类中定义的函数会"隐藏"基类中同名的函数,无论参数列表是否相同,基类的同名函数都会被隐藏。

通过派生类对象无法直接访问被隐藏的基类函数,需要使用 对象::基类名::函数 的格式才能访问。

2 原理

C++的名称查找遵循以下规则:

  1. 首先在当前类作用域中查找名称

  2. 如果找到,停止查找(即使有更好的匹配在基类中)

  3. 如果没找到,才会在基类中继续查找

这意味着当派生类定义了某个名称的函数时,编译器会优先选择派生类中的版本,完全忽略基类中的同名函数。

3 场景

3.1 函数隐藏 - 同名同参数

#include <iostream>

class Base {
 public:
  void print() {  // 非虚函数
    std::cout << "Base" << std::endl;
  }
};

class Derive : public Base {
 public:
  void print() {  // 隐藏了Base::print(),不是重写
    std::cout << "Derive" << std::endl;
  }
};

int main() {
  Derive d;
  d.print();        // 输出: "Derive"
  d.Base::print();  // 输出: "Base" - 需要显式指定基类
  
  Base* b = &d;
  b->print();       // 输出: "Base" - 不是多态行为
  
  return 0;
}

3.2 函数隐藏 - 同名不同参

#include <iostream>

class Base {
 public:
  void print() {  // 无参数的print函数
    std::cout << "Base" << std::endl;
  }
};

class Derive : public Base {
 public:
  void print(int val) {  // 带参数的print函数,隐藏了Base::print()
    std::cout << "Derive: " << val << std::endl;
  }
};

int main() {
  Derive d;
  d.print(42);      // 正确:调用Derive::print(int)
  // d.print();     // 错误:Base::print()被隐藏,无法直接调用
  
  d.Base::print();  // 正确:需要显式指定基类作用域
  
  Base* b = &d;
  b->print();       // 正确:调用Base::print()
  
  return 0;
}

4 解决

有以下方法:

  • 基类的同名函数使用 virtual 修饰,实现多态;

  • 在派生类中使用 using 声明基类中的同名函数(只适用于“同名不同参”);

  • 在派生类中显示定义一个新的转发函数,封装基类里的同名函数,也就是在在派生类中使用了同名函数重载(只适用于“同名不同参”);

  • 在基类和派生类中使用不同的函数名;

代码示例(使用 using):

class Derived : public Base {
public:
    using Base::func; // 引入Base中的所有func函数
    void func(double x) { cout << "Derived::func(double)" << endl; }
};

// 现在可以使用:
// Derived d;
// d.func();      // 调用Base::func()
// d.func(42);    // 调用Base::func(int)
// d.func(3.14);  // 调用Derived::func(double)

0

评论区