Skip to content

mropert Polymorphic ducks

NOTE:

1、其实这篇文章是对 Sean Parent的paper的说明

The problem with traditional inheritance

Consider the following:

class Drawable {
public:
   virtual ~Drawable() {}
   virtual void draw(Display& display) const = 0;
};

Here we have a bunch of objects we want to draw. We can’t know at runtime which ones we will have, only that at some point we will go through a list of them and draw them on a given Display with a call to draw(). This is all we care about. But we got a lot more for our trouble:

All of our drawable objects must inherit Drawable and implement draw(), which means each of them has to know how to draw itself (or save, or load, or compute or…) which is a clear violation of the principle of separation of concerns1. I could stop there in my list of problems, we already reached the point of no return by coupling our implementation much more that it reasonably should.

But it goes on:

1、We can’t copy-construct or copy-assign our objects anymore, at best we can implement a clone() virtual method everywhere.

NOTE:

1、virtual clone polymorphic type

2、显然,如果每个地方都需要添加一下的话,那么这就是**intrusive**的。

2、We can’t have a list (or array or set or…) of our objects, we need a list of Drawable* (or a std::unique_ptr<Drawable>). It prevents us from using most standard algorithms which expect values and not pointers.

NOTE: 没有理解

3、We can’t store them by value, an owning container will have to new each one instead of putting them in a contiguous buffer or on the stack, which is terrible for modern CPUs caches.

NOTE:

1、tag-value semantic and reference semantic-stack heap CPU cache-performance

2、value semantic

4、Our code will get cluttered with calls to new or std::make_unique everytime we want to create a drawable.

Alternatives

In his talk at CppCon 2017, Louis Dionne showed a bunch of alternative techniques around that problem which I found interesting but ultimately too complex to present here2.

Instead, I propose we simply use the time tested technique of WWSPD: What Would Sean Parent Do?

NOTE: 其实就是: polymorphic value type idiom

If you answered std::rotate(), nice try but unfortunately it was not the right answer this time. No, the right answer was presented in his talk: Better Code: Runtime Polymorphism. Here’s how it works:


NOTEl 后面就是开始将implementation,这是炒剩饭,没有什么新意。

Erasing the type

Getting rid of member functions

Wrapping-up