首页 > 解决方案 > 名称隐藏和覆盖 - 有没有办法使函数显式不覆盖

问题描述

我想隐藏一个虚拟方法而不是覆盖。我知道出于历史/兼容性原因,覆盖说明符是可选的,并且覆盖是隐式发生的。为了停止覆盖,我通常通过添加默认的“虚拟”参数来调整签名。有没有更好的办法?

假设这段代码:

#include <iostream>

class A{
public:
    virtual void Foo()
    {
        std::cout << "A::Foo";
    }
};

class B : public A
{
public:
    void Foo() /*not override, just hide*/
    {
        std::cout << "B::Foo";
    }
};

int main()
{
    B b{};
    A& a = b;
    a.Foo(); //should print A::Foo - but prints B::Foo
}

到目前为止我所做的是:

#include <iostream>

class A{
public:
    virtual void Foo()
    {
        std::cout << "A::Foo";
    }
};

template<typename T>
class reintroduce{};

class B : public A
{
public:
    void Foo(reintroduce<B> = {}) /*not override, just hide*/
    {
        std::cout << "B::Foo";
    }
};

int main()
{
    B b{};
    A& a = b;
    a.Foo(); //should print A::Foo
}

标签: c++c++20name-hiding

解决方案


这个问题对“隐藏”的要求不太清楚,但以下有效地“隐藏”了派生类中的继承方法,同时不改变其在基类中的可见性/可访问性。

#include <iostream>

class A {
public:
    virtual void Foo()
    {   std::cout << "A::Foo"; }
};

class B : public A
{
private:
    using A::Foo;
};

int main()
{
    B b;
    b.Foo();     // error, cannot access private member
    b.A::Foo();  // ok, calls A::Foo

    A& a = b;
    a.Foo();     // ok, calls A::Foo
}

推荐阅读