面试题答案
一键面试成员函数隐藏(hiding)
- 定义:当派生类定义了一个与基类中同名的成员函数(无论参数列表是否相同),基类中的该函数在派生类中就被隐藏了。此时通过派生类对象调用该函数名,只会调用到派生类的函数。
- 示例代码:
#include <iostream>
class Base {
public:
void func() {
std::cout << "Base::func()" << std::endl;
}
};
class Derived : public Base {
public:
void func(int i) {
std::cout << "Derived::func(int) with value " << i << std::endl;
}
};
int main() {
Derived d;
d.func(5); // 调用 Derived::func(int)
// d.func(); // 错误,Base::func() 被隐藏
Base* b = &d;
b->func(); // 调用 Base::func()
return 0;
}
成员函数覆盖(overriding)
- 定义:发生在继承体系中,当派生类提供一个与基类中虚函数(virtual)具有相同签名(函数名、参数列表、返回类型)的函数实现时,这种情况称为覆盖。通过基类指针或引用调用虚函数时,会根据对象的实际类型(动态绑定)来决定调用哪个函数。
- 示例代码:
#include <iostream>
class Base {
public:
virtual void func() {
std::cout << "Base::func()" << std::endl;
}
};
class Derived : public Base {
public:
void func() override {
std::cout << "Derived::func()" << std::endl;
}
};
int main() {
Base* b1 = new Base();
Base* b2 = new Derived();
b1->func(); // 调用 Base::func()
b2->func(); // 调用 Derived::func(),动态绑定
delete b1;
delete b2;
return 0;
}
总结:
- 隐藏强调的是同名函数,参数列表可以不同,通过派生类对象调用同名函数时会隐藏基类函数。
- 覆盖强调的是虚函数,参数列表和返回类型必须与基类虚函数相同,通过基类指针或引用调用虚函数时实现动态绑定。