What is illegal is:
Employee is an abstract base class. This line:
Employee joe;
is illegal on its own, it is creating an instance of your abstract class.
joe = HourlyEmployee();
is a bad idea even if the classes were both complete as it would slice. joe is an object, not a reference.
If HourlyEmployee remains abstract (does not implement printCheck()) then of course your line is illegal because you are creating a (temporary) instance of one.
Incidentally if both classes were complete, thus the code compiled, but printCheck() remained virtual (not pure), then
joe.printCheck();
would invoke the Employee version not the HourlyEmployee version because joe is of type Employee and remains so in spite of the assignment. That is why slicing is mostly a bad idea.
solved Polymorphism and pure virtual functions [closed]