使用派生的 class 参数覆盖函数是否被认为是名称隐藏?

Is overriding a function with derived class argument considered name hiding?

我这算是隐姓埋名吗?
根据输出,它是:

class A
{
public:
    A(){}
    virtual bool f(A& a) {
        std::cout << "A" << std::endl;
        return true;
    }
};

class B : public A
{
    std::string s;
public:
    B(){}
    bool f(B& a) {
        std::cout << "B" << std::endl;
        return s == a.s;
    }
};

int main()
{
    A* a = new B;
    B b;
    a->f(b);
}

这会打印 A,如果我想实现多态行为,我需要使派生的 class's f's 参数与基础 classes 相同。但在那种情况下,我无法访问派生的 class 函数中的 s 。这是设计僵局还是我搞砸了 OOD 原则?

您似乎想要多次分派。

Double dispatch模式是一个解决方案。

使用 c++17,我们有 std::variant 可以为我们进行调度:

class A;
class B;

using VariantA = std::variant<A*, B*, C*>;
using VariantConstA = std::variant<const A*, const B*, const C*>;

class A
{
public:
    virtual ~A() = default;
    virtual VariantA AsVariant() { return this; }
    virtual VariantConstA AsVariant() const { return this; }

    friend bool operator==(const A&, const A&);
};

class B : public A
{
    std::string s;
public:
    B(std::string s) : s(s) {}
    VariantA AsVariant() override { return this; }
    VariantConstA AsVariant() const override { return this; }

    friend bool operator==(const B& lhs, const B& rhs);
};

// class C

struct EqualVisitor
{
    template <typename T>
    bool operator() (const T& lhs, const T& rhs) const { return lhs == rhs; }

    template <typename T1, typename T2>
    bool operator() (const T1&, const T2&) const { return false; }
};


bool AreEqual(const A& lhs, const A& rhs)
{
    return std::visit(EqualVisitor{}, lhs.AsVariant(), rhs.AsVariant());
}

Demo