#include<typeinfo>
#include<iostream>
using namespace std;

class Base{
	friend bool operator==(const Base&, const Base&);
public:
	Base(int i) :base(i){}
	virtual ~Base() = default;
	int base;
protected:
	virtual bool equal(const  Base&) const;
};

class Derived :public Base{
public:
	Derived(int i,int j) :Base(i),derived(j){}
	int derived;
protected:
	bool equal(const Base&) const;
};

bool operator==(const Base &lhs, const Base &rhs)
{
	cout << "\toperator==(base&, base&)\n";
	return typeid(lhs) == typeid(rhs) && lhs.equal(rhs);
}

bool Derived::equal(const Base &rhs) const
{
	cout << "\tDerived::equal(Base&)\n";
	auto r = dynamic_cast<const Derived&>(rhs);
	return derived == r.derived && (Base::equal(rhs));
}

bool Base::equal(const Base &rhs) const
{
	cout << "\tBase::equal(Base&)\n";
	return base == rhs.base;
}

int main(){
	Base b1(1), b2(2);
	Derived d1(1, 11), d2(2, 22);
	if (d1 == b1)
		cout << "Yes";
	else
		cout << "No";
	cout << endl;
	
	Derived &d3 = dynamic_cast<Derived&>(d1);
	cout << d3.derived;
        //error
	//Derived &d4 = dynamic_cast<Derived&>(b1);
	//cout << d4.derived;
}