Reputation: 6546
I is this considered name hiding?
As according to the output it is:
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);
}
This prints A
, and if I want to achieve the polymorphic behaviour, I need to make the derived class's f's
argument the same as the base classes. But in that case I don't have access to s in the derived class function. Is this a design deadlock or I am messing up the OOD principles?
Upvotes: 0
Views: 60
Reputation: 217275
It seems you want multiple dispatch.
Double dispatch pattern is a solution.
With c++17, we have std::variant
which might do the dispatching for us:
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());
}
Upvotes: 2