After reading up on them in terms of class hierarchy, they seem to just be almost like comments, to remind you that all classes use this sort of function

Recommended Answers

All 4 Replies

After reading up on them in terms of class hierarchy, they seem to just be almost like comments, to remind you that all classes use this sort of function

???!!!
It's a false statement (or I misunderstand the post).

When you mark a method of your class as virtual you give the user of your class the possibility to override that method. If you don't, the metod can't be overridden.

When you mark a method of your class as virtual you give the user of your class the possibility to override that method. If you don't, the metod can't be overridden.

That statement is inaccurate on so many levels that I'm speechless. Non-virtual functions can also be overridden, but the behaviour differs from overridden virtual functions due to "name hiding", as described in the C++ standard.

The point of virtual member functions is that they allow functionality to be specified in a base class, and specialised in a derived class. For example, a generic Shape class might declare a virtual function named Area() to compute it's area, and another virtual function called Name(). Derived classes (which represent particular shapes) override those virtual function to give appropriate results for particular shapes.

class Shape
{
     public:
          Shape();
          virtual double Area() const = 0;
          virtual std::string Name() const = 0;
};

class Triangle: public Shape
{
     public:
          Triangle(double h, double w) : height(h), width(w) {};
          double Area() const {return 0.5*height*width;};

          std::string Name() const {return "Triangle";}

     private:
          double height, width;
};

class Circle : public Shape
{
     public:
         Circle(double r): radius(r) {};
         virtual double Area() const {return 4.0*atan(1.0)*radius*radius;};
          virtual std::string Name() const {return "Circle";}
      private:
            double radius;
};

Now, let's say we have a function that only knows about the Shape class, and wishes to print its name and area. For example;

void PrintArea(const Shape &s)
{
    std::cout << s.Name() << " - Area = " << s.Area() << '\n';
}

This function can be passed any Shape object by reference, and will print out information about the actual shape passed.

This is described as polymorphic behaviour: the class Shape is a polymorphic base class, derived classes modify it's behaviour, but the interface seen by the PrintArea() function is the same for all the classes. The PrintArea() function only receives generic information about a Shape (i.e. it provides a Name() and Area() member function) but, at run time, the behaviours correspond to the actual type of the object passed.

For example;

int main()
{
     Triangle tri(2.0, 4.0);
     Circle cir(5.0);

      PrintArea(tri);   //   will print "Triangle - Area = 4"
      PrintArea(cir);  //    will print "Circle - Area = 78.5"  (possibly higher precision value)

      Shape *s[2];
      s[1] = &cir;
      s[0] = &tri;

       // this loop will print out the above lines of output in reverse order
      for (int i = 0; i < 2; ++i)
          PrintArea(s[i]);
}
commented: you made a point +3
commented: Excellent Post +1

Thanks for the clarification.
I saw the forrest but forgot about the trees...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.