Inheritance Is The Base Class of Evil

aghuttun · 41K views · 2013 · 24:20

Open on YouTube

C, C++, Rust, Go & systems languagesSoftware architecture & designtalk

Why Stack Overflow recommends it

Stack Overflow users link it when explaining type erasure, value-semantic polymorphism, and why to avoid deep inheritance hierarchies in C++.

Recommended by 6 people across 6 different months, 2015 to 2022.

What it is

A 2013 GoingNative talk by Sean Parent (Adobe) arguing that inheritance-based polymorphism is intrusive and harms code. He shows how to build non-intrusive, runtime-polymorphic objects with value semantics, including a multiple-undo example, using the concept/model type erasure idiom in C++.

What people said

Recommends MikeMB · 2015-10 · Stack Overflow · on “Arrays of Pointers to Abstract Types”

@WillyGoat: there is actually a very nice extension to this pattern, that doesn't require a clone method, that is explained in this talk: [this video] It has the advantage, that it is non-intrusive, but the internals of manager become quite complicated. Maybe I'll update my answer later.

Recommends Denis Yaroshevskiy · 2016-05 · Stack Overflow · on “What's the right way to overload operator== for a class hierarchy?”

I think this looks weird: void foo(const MyClass& lhs, const MyClass& rhs) { if (lhs == rhs) { MyClass tmp = rhs; // is tmp == rhs true? } } If implementing operator== seems like a legit question, consider type erasure (consider type erasure anyways, it's a lovely technique). Here is Sean Parent describing it. [this video] Then you still have to do some multiple-dispatching. It's an unpleasant problem. Here is a talk about it. [LINK] Consider using variants instead of hierarchy. They can do this type of things easyly.

Recommends JohnB · 2016-06 · Stack Overflow · on “Cannot convert parameter 1 from 'Component<W> *' to 'Component<W> *'”

@Devolus: You might want to have a look at this talk, I guess: [this video] It is about avoiding deep inheritance hierarchies when interfacing existing frameworks.

Recommends Louis Langholtz · 2018-05 · Stack Overflow · on “How to correctly store/pass a variable of interface type (modern c++)?”

There is no one-and-only correct answer to the questions you're asking. There are different ways of storing/passing variables that are interfaces and you've mentioned some of those ways. Some other ways of dealing with this depend on what you're ultimately trying to achieve. For instance, if you're ultimately concerned about having polymorphic behavior and you're not tied to that being a design/type detail, you can also consider using type erasure and storing/passing these entities by value (semantically speaking). As to the how and why you might want to do it this way — which also addresses your question regarding issues with using inheritance — I'd suggest watching Sean Parent's talk: Inhe

Recommends Louis Langholtz · 2018-05 · Stack Overflow · on “creating a class with two possible inheritances”

As to whether the design you've shown is a good idea, the CodeReview [LINK] site is more appropriate for such questions of opinion. But while we're on this subject, there are those (like Sean Parent) who suggest that inheritance should be an implementation detail [this video] ; not an interface detail like you've used it.

Recommends aayushp · 2021-05 · Stack Overflow · on “Deduce return type of a function on derived class automatically on base class”

An abstract base class is generally intended as a public interface to the implementation class. In this case your interface is changing with every child: when the return type changes, the function signature changes and that is why override will result in compilation error as you might have already realized. Visitor is useful provided your class system is stable as described here [LINK] : Confirm that the current hierarchy (known as the Element hierarchy) will be fairly stable and that the public interface of these classes is sufficient for the access the Visitor classes will require. If these conditions are not met, then the Visitor pattern is not a good match. To implement Visitor, you woul

Recommends user2138149 · 2022-08 · Stack Overflow · on “Windows build source fails silently due to use of {} for initialization rather than () - why?”

To address the questions about infinite recursion: The answer is no, due to value symantics. You can find a video about this here: [this video] And you can find the source code here: [LINK]

Cites Corristo · 2017-04 · Stack Overflow · on “Dependency inversion (from S.O.L.I.D principles) in C++”

Note that C++ is not an object-oriented programming language, but rather lets the programmer choose between many different paradigms. One of the key principles of C++ is that of zero-cost abstractions, which in particular entails to build abstractions in such a way that users don't pay for what they don't use. The C#/Java style of defining interfaces with virtual methods that are then implemented by derived classes don't fall into that category though, because even if you don't need the polymorphic behavior, were std::string implementing a virtual interface, every call of one of its methods would incur a vtable lookup. This is unacceptable for classes in the C++ standard library supposed to

Cites Ricardo Perl · 2018-09 · Stack Overflow · on “How to allow custom return types of member functions for type erasure in C++?”

Over the last years, type erasure or concept-based runtime polymorphism became quite popular, see e.g. the talks by Sean Parent Better Code: Runtime Polymorphism [LINK] , Inheritance Is The Base Class of Evil [this video] or C++ Seasoning [LINK] resp. the implementations by Adobe [LINK] , Facebook [LINK] , Boost.TypeErasure [LINK] , Boost.te [LINK] or dyno [LINK] . Here is an example from Sean Parent's talk: class object_t { struct concept_t { virtual ~concept_t() = default; virtual void draw_(ostream&, size_t) const = 0; }; template <typename T> struct model final : concept_t { model(T x) : data_(move(x)) { } void draw_(ostream& out, size_t position) const override { draw(data_, out, position);

Cites alfC · 2019-08 · Stack Overflow · on “Why do we need virtual functions in C++?”

@user3530616, yes I would add "with your old code AND even with your old binaries (compiled code). This is extremely powerful, however one pays a big price for this flexibility and it is most of the time unnecessary. [this video] If you can recompile and not depend on stable binaries or don't need runtime linking, there are better options that are easier to reason about. Late binding can be done with templates in other cases and it is more powerful but in other senses (mathematical or value-semantics reasoning).