For starters, your assignment operators lack
return statements even though they are declared (rightfully) to return something.
As for your main(),
foo = derived;
This makes a call to
Derived::operator=, which, in your implementation, explicitly calls
Base::operator=, which performs the assignment.
((Base) derived).Base::operator=(base);
This copy-constructs a temporary nameless object of type Base using a reference to
derived as its argument, and calls
Base::oeprator= to assign from
base to it. The temporary nameless Base, which now holds a copy of the value 22, is then destructed at the semicolon with no lasting effects.
derived.Base::operator=(base);
This calls
Base::operator= on the Derived instance called "derived" using a Base called base as its argument. It performs the assignment as programmed.
What exactly do you want to prevent?
Note that, in general, a derived class cannot have "tighter restrictions" than the base class: a circle is not an ellipse
http://en.wikipedia.org/wiki/Circle-ellipse_problem