1

Following the quote from the user Steve314's answer on Why do we need virtual functions in C++?:

With "virtual" you get "late binding". Which implementation of the method is used gets decided at run time based on the type of the pointed-to object - what it was originally constructed as. This is not necessarily what you'd think based on the type of the pointer that points to that object.

I stumbled upon the following example:

class Shape
{
    std::string name;
    friend std::ostream& operator<<(std::ostream&, const Shape&);
public:
    Shape(const std::string&);
    virtual double circumference() = 0; 
    virtual ~Shape() {}
protected:
    virtual void print(std::ostream&) const;
};

In the classes that inherit from Shape (e.g. Circle, Square...), virtual functions are overridden. Such is the case with the method circumference().

My question is as follows: if circumference() is an abstract method that cannot be called (since Shape is an abstract class), why do we make it a virtual function and not simply leave it being abstract and override it as usual in derived classes?

If I understand correctly, we make a method virtual to ensure "late binding". E.g. If we were to have the following block of code:

Shape *circle = new Circle();
double circ = circle->circumference();

with making circumference() virtual we ensure that the method of the class type of our pointed-to object will be called, and not the method of the "declared" type (here we want to call the method of the Circle class).

So, if calling circumference() of the class Shape in any way would cause a compile-time error (making it impossible to occur) why do we make it virtual and not just abstract?

0lt
  • 283
  • 2
  • 13
  • _"virtual and not just abstract?"_ Because the combination of `virtual` and `= 0;` exactly is how to make the function _abstract_. – user0042 Dec 09 '17 at 13:10
  • Only virtual functions can be abstract. Non-virtual functions can't be overridden. – molbdnilo Dec 09 '17 at 13:12

1 Answers1

4

A virtual method with = 0 appended is the definition of an abstract method. There's no such thing as an abstract method without the virtual keyword.

double circumference() = 0; 

This is simply a syntax error. A non-virtual method must have a definition. It can't be abstract and have = 0.

Think of it this way:

  1. Does the method require late binding, such that the exact implementation called will vary at runtime? If so, then mark it virtual.
  2. If it's virtual, does the base class want to provide a default implementation? If not, then add = 0.

You can't do step 2 without step 1.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • I thought the code you provided *was* the way to make an abstract function. Turns out that virtual + pure = abstract. https://stackoverflow.com/questions/6574852/are-abstract-methods-and-pure-virtual-functions-the-same-thing#6574953 Still, it confuses me how the concept of the *abstract* method fits with the semantics of *virtual* described in the quoted text. – 0lt Dec 09 '17 at 13:17
  • 2
    "*If it's `virtual`, does the base class want to provide a default implementation? If not, then add `= 0`.*" An abstract method can have a default implementation. It is not commonly done, but it is allowed. Marking a method as abstract simply means that it MUST be overwritten. But an overriden method can call a base class abstract method if it has a default implementation. – Remy Lebeau Dec 10 '17 at 10:29