Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why derive from a concrete class is a poor design

Tags:

I was reading about NonVirtual Interface pattern: Herb Sutter is talking about why virtual function must be private in most of the case, protected in some case and never public.

But at the end of the article he write:

Don't derive from concrete classes. Or, as Scott Meyers puts it in Item 33 of More Effective C++,[8] "Make non-leaf classes abstract." (Admittedly, it can happen in practice - in code written by someone else, of course, not by you! - and in this one case you may have to have a public virtual destructor just to accommodate what's already a poor design. Better to refactor and fix the design, though, if you can.)

But I don't understand why this is a poor design

like image 560
Elvis Dukaj Avatar asked May 23 '13 22:05

Elvis Dukaj


People also ask

What does a concrete class not have purpose?

A concrete class cannot have an abstract method, because class containing an abstract method must also be abstract.

Does concrete class have purpose?

A concrete class is a class that has an implementation for all of its methods. They cannot have any unimplemented methods. It can also extend an abstract class or implement an interface as long as it implements all their methods. It is a complete class and can be instantiated.

What does concrete class mean?

What Is a Concrete Class? A concrete class is a class that we can create an instance of, using the new keyword. In other words, it's a full implementation of its blueprint. A concrete class is complete.

Can a concrete class have an abstract subclass?

A subclass can be abstract even if its superclass is concrete. For example, the Object class is concrete, but may have an abstract subclass like GeometricObject . A subclass may override a method from its superclass to declare it abstract.


1 Answers

You could buy a copy of More Effective C++, or check your local library for a copy, and read item 33 for the full explanation. The explanation given there is that it makes your class prone to partial assignment, also known as slicing:

There are two problems here. First, the assignment operator invoked on the last line is that of the Animal class, even though the objects involved are of type Lizard. As a result, only the Animal part of liz1 will be modified. This is a partial assignment. After the assignment, liz1's Animal members have the values they got from liz2, but liz1's Lizard members remain unchanged.

The second problem is that real programmers write code like this. It's not uncommon to make assignments to objects through pointers, especially for experienced C programmers who have moved to C++. That being the case, we'd like to make the assignment behave in a more reasonable fashion. As Item 32 points out, our classes should be easy to use correctly and difficult to use incorrectly, and the classes in the hierarchy above are easy to use incorrectly.

See this question and others for a description of the object slicing problem in C++.

Item 33 also says this, later on:

Replacement of a concrete base class like Animal with an abstract base class like AbstractAnimal yields benefits far beyond simply making the behavior of operator= easier to understand. It also reduces the chances that you'll try to treat arrays polymorphically, the unpleasant consequences of which are examined in Item 3. The most significant benefit of the technique, however, occurs at the design level, because replacing concrete base classes with abstract base classes forces you to explicitly recognize the existence of useful abstractions. That is, it makes you create new abstract classes for useful concepts, even if you aren't aware of the fact that the useful concepts exist.

like image 114
rob mayoff Avatar answered Nov 15 '22 11:11

rob mayoff