Objects, pointers and polymorphism Neil Moore, Adobe

I want to describe my recent conceptual struggles and things I've learned about using polymorphism in C++.

Inclusion polymorphism - types inherit code and data from their parents, a.k.a. dynamic dispatch, etc.

Parametric polymorphism - operate on different types having features in common, not part of a hierarchy.

Basic definitions

Basic example - no polymorphism

Code sample with no use of subtyping

This is fine - we get exactly what we expect, i.e. the definition of add from the variable's type.

Basic example 2 - what no DD?

Code sample exhibiting static type and slicing

This feels a bit wrong. We get the definition of add from the type of the variable, not the type of the thing assigned into it.

Subtype polymorphism is not happening

The same program in Java would have a different result

In addition we got slicing

Basic example 3 - the curate's egg

Dynamic dispatch using pointers and references

Now we are doing dynamic dispatch of add, because we called the instance method from a pointer or reference.

I didn't really want pointers or references, I just wanted dynamic dispatch.

Why not use pointers?

  • It's easy to make a mistake with memory allocation when using pointers
  • Pointer sharing makes local reasoning about a program harder
  • Pointers can be shared around between threads creating races

Improvement 1 - safe pointer

It is not hard to make memory allocation safe by using a safe pointer

But this is really not much better than a global variable.

  • It can end up anywhere.
  • Anybody who has the variable can use it any time

We were always told to share as children, but it's time to forget that advice

Now I'm going to introduce a new type hierarchy

New basic definitions

Improvement 2 - unique ownership

Could a real expert tell me why I don't get an error for that last line?

With unique pointers we have achieved memory safety and also single ownership

But the client code is a bit awkward

Using boost type erasure provides a solution

Not that type of Erasure

The boost kind is preferable!

Final improvement - polymorphism and value semantics

Definitions and traits using type erasure

Note that there is no type hierarchy here

Hence we are using parametric polymorphism and not subtype polymorphism

I haven't got deeply into the boost package yet to figure out if you can also do dynamic dispatch with a boost::any but I suspect so

But you can always use inclusion rather than inheritance which I think is a good idea but it's s whole other talk

Client code with boost type erasure

Now we have all the advantages of the previous examples plus value semantics

Hence copying things using var = val works nicely

Conclusions

Don't need to accept the need to use raw pointers or references to get polymorphism

Go a step beyond safe pointer types to also get value semantics

References

This talk is highly derivative of a number of talks and articles I've read recently.

http://www.bigoh.co.uk/c++/2014/11/30/objects-and-pointers.html

http://www.bigoh.co.uk/c++/2015/07/21/objects-and-pointers-2.html

Had to leave out a few techniques:

  • Curiously recurring template pattern
  • Looking at how boost type erasure could be implemented

Made with Adobe Slate

Make your words and images move.

Get Slate

Report Abuse

If you feel that this video content violates the Adobe Terms of Use, you may report this content by filling out this quick form.

To report a Copyright Violation, please follow Section 17 in the Terms of Use.