使用派生的 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());
}
我这算是隐姓埋名吗?
根据输出,它是:
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());
}