In a comment you explain that
“i get the error: undefined reference to `Shape::Shape()'”
That means that you have forgotten to provide an implementation of that constructor.
Now, with the technical problem fixed, look at the design.
The first two methods suffer from two maladies: (1) although they should never mutate an object they are not declared const
, so they cannot be called on a const
object, and (2) the get
prefix reduces readability, is more to type and has no general advantage. I’ve found a get
prefix useful in some rare circumstances as a disambiguation device, but all usages I’ve seen by beginners have been inappropriate copying of a Java convention, which makes sense in Java but not in C++. So, instead of …
virtual double getArea();
virtual void printDraw();
do
virtual double area() const;
virtual void print() const;
Then, the method …
bool isLegal(Shape shape);
is wrong in so many ways… Ouch! But let’s start with the purely technical.
From a purely technical point of view it is needlessly inefficient to pass the argument by value, which incurs a copy operation for each call. Instead pass the object by reference. And make that a reference to const
, in order to support const
objects and rvalue objects as arguments:
bool isLegal(Shape const& shape);
Next, naming: isLegal
is an ungood name because most any C++ object will be legal. It would have to be, say, pornographic and residing in a non-Western country, in order to become illegal. And I can’t for the life of me think of any way to make an object pornographic, or make it reside in some specific geographic region.
So,
bool isValid(Shape const& shape);
Next, low level design, there is no good reason to have that non-virtual
method as an ordinary member function, because that requires that you call it on an object. But all the information it needs is in the ordinary argument. We can see this confusion in the derived class, where …
bool isLegal(Trig trig);//override
is not at all an override: it's technically an overload of the function name, which means, just a different function with the same name. There’s no virtuality here, no override. And it is not needed.
So, make that a static
member function, which does not have to be called on an object:
static bool isValid(Shape const& shape);
Finally, higher level design, the whole machinery of C++ constructors and destructors is there in order to avoid such methods and checking.
The idea is that you …
Then the object simply can’t become invalid. This approach is called single phase construction, and the properties of the object that makes it “valid’ are known as the class’ class invariant. Which should be established by every constructor, and maintained by every method.
This means, final version, the isValid
function IS REMOVED: it has no job to do, because that job is (properly) done by the constructor(s) and the methods.
Okay, there are some technical challenges with single phase construction, in particular how to do derived class specific initialization in a base class constructor. This is covered by the C++ FAQ. It’s often a good idea to read the FAQ.