gpt4 book ai didi

c++ - 覆盖虚函数和隐藏非虚函数有什么区别?

转载 作者:IT老高 更新时间:2023-10-28 21:37:06 31 4
gpt4 key购买 nike

给定以下代码片段,函数调用有什么区别?什么是函数隐藏?什么是函数覆盖?它们与函数重载有什么关系?两者有什么区别?我在一个地方找不到对这些的详细描述,所以我在这里询问,以便我可以整合信息。

class Parent {
public:
void doA() { cout << "doA in Parent" << endl; }
virtual void doB() { cout << "doB in Parent" << endl; }
};

class Child : public Parent {
public:
void doA() { cout << "doA in Child" << endl; }
void doB() { cout << "doB in Child" << endl; }
};

Parent* p1 = new Parent();
Parent* p2 = new Child();
Child* cp = new Child();

void testStuff() {
p1->doA();
p2->doA();
cp->doA();

p1->doB();
p2->doB();
cp->doB();
}

最佳答案

什么是函数隐藏?

... 是名称隐藏的一种形式。一个简单的例子:

void foo(int);
namespace X
{
void foo();

void bar()
{
foo(42); // will not find `::foo`
// because `X::foo` hides it
}
}

这也适用于基类中的名称查找:

class Base
{
public:
void foo(int);
};

class Derived : public Base
{
public:
void foo();
void bar()
{
foo(42); // will not find `Base::foo`
// because `Derived::foo` hides it
}
};

什么是函数覆盖?

这与虚函数的概念有关。 [class.virtual]/2

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

class Base
{
private:
virtual void vf(int) const &&;
virtual void vf2(int);
virtual Base* vf3(int);
};

class Derived : public Base
{
public: // accessibility doesn't matter!
void vf(int) const &&; // overrides `Base::vf(int) const &&`
void vf2(/*int*/); // does NOT override `Base::vf2`
Derived* vf3(int); // DOES override `Base::vf3` (covariant return type)
};

调用虚函数时,最终的覆盖器变得相关:[class.virtual]/2

A virtual member function C::vf of a class object S is a final overrider unless the most derived class of which S is a base class subobject (if any) declares or inherits another member function that overrides vf.

即如果您有一个 S 类型的对象,则最终覆盖器是您在遍历 S 的类层次结构返回其基类时看到的第一个覆盖器。重要的一点是函数调用表达式的动态类型用于确定最终的覆盖器:

Base* p = new Derived;
p -> vf(42); // dynamic type of `*p` is `Derived`

Base& b = *p;
b . vf(42); // dynamic type of `b` is `Derived`

覆盖和隐藏有什么区别?

本质上,基类中的函数总是被派生类中的同名函数隐藏;无论派生类中的函数是否覆盖基类的虚函数:

class Base
{
private:
virtual void vf(int);
virtual void vf2(int);
};

class Derived : public Base
{
public:
void vf(); // doesn't override, but hides `Base::vf(int)`
void vf2(int); // overrides and hides `Base::vf2(int)`
};

要查找函数名,使用表达式的静态类型:

Derived d;
d.vf(42); // `vf` is found as `Derived::vf()`, this call is ill-formed
// (too many arguments)

它们与函数重载有何关系?

由于“函数隐藏”是名称隐藏的一种形式,如果函数名称被隐藏,所有重载都会受到影响:

class Base
{
private:
virtual void vf(int);
virtual void vf(double);
};

class Derived : public Base
{
public:
void vf(); // hides `Base::vf(int)` and `Base::vf(double)`
};

对于函数重写,只会重写基类中具有相同参数的函数;你当然可以重载一个虚函数:

class Base
{
private:
virtual void vf(int);
virtual void vf(double);
void vf(char); // will be hidden by overrides in a derived class
};

class Derived : public Base
{
public:
void vf(int); // overrides `Base::vf(int)`
void vf(double); // overrides `Base::vf(double)`
};

关于c++ - 覆盖虚函数和隐藏非虚函数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19736281/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com