Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As you've noticed, in your example code there is no point having separate base and derived classes.</p> <p><em>In general</em>, the purpose of classes with virtual functions is dynamic polymorphism, but your code hasn't used it.</p> <p>Suppose you had some code that used a <code>base*</code> without knowing <em>which</em> (of several) derived classes it actually points to. Suppose that they each have different implementations of <code>abstract()</code>. Suppose that you want to <em>force</em> anyone who writes a derived class of <code>base</code> to implement their own version of <code>abstract()</code>. Then there's a reason to make <code>abstract()</code> a pure virtual function and hence a reason for <code>base</code> to be an abstract class:</p> <pre><code>#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;ctime&gt; struct Base { virtual void abstract() = 0; virtual ~Base() {}; }; struct Derived1 : Base { void abstract() { std::cout &lt;&lt; "Derived1\n"; } }; struct Derived2 : Base { void abstract() { std::cout &lt;&lt; "Derived2\n"; } }; Base *random_object() { if (std::rand() &lt; RAND_MAX/2) { return new Derived1(); } else { return new Derived2(); } } int main() { std::srand(std::time(0)); Base *b = random_object(); b-&gt;abstract(); delete b; } </code></pre> <p>The code in <code>main</code> only cares about <code>Base</code>, it doesn't need to know anything about derived classes beyond the fact that there might be some. Only the code in <code>random_object</code> knows about the derived classes. Meanwhile <code>Base</code> doesn't need to know how <code>abstract()</code> is implemented, only the derived classes do (and each one only cares about its own implementation). It's good for code not to need to know about things -- it means those things can be changed without touching the code that doesn't care.</p> <p>There are also some high-level design issues around using a non-abstract class as a public base class. For example, it's quite easy to unthinkingly write code that won't work as you expect once some of your functions have been overridden, and it's quite easy to accidentally slice an object with a concrete base class. So there's a philosophy that says you should know at all times whether you're writing a concrete class or a base class, and not try to do both at once. When you follow this philosophy, all base classes are abstract, so you make a class abstract to signal that it is designed to be derived from.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload