[webkit-dev] Quick intro: FINAL and OVERRIDE

Andreas Kling akling at apple.com
Fri Jul 26 10:43:16 PDT 2013


Hi WebKittens!

I’m about to re-land <http://webkit.org/b/115977> now that the OS X bots have had their clang installations updated.

Let me take a moment to explain what FINAL and OVERRIDE do, and how to apply them.

OVERRIDE is used to decorate virtual methods that override a method inherited from a superclass. This makes the code slightly more self-documenting but more importantly, gives us a compiler warning if there is no superclass method with the same signature. In other words, OVERRIDE protects you from forgetting to update subclasses when changing the signature of a method in a superclass.

Example of OVERRIDE:

class Human { 
public:
    virtual void eat();
};

class Anders : public Human { 
public:
    virtual void eat() OVERRIDE;
};

If you rename eat() to drink() in “B”, you’ll get a compiler warning:
huehuehue.cpp:8:15: error: 'drink' marked 'override' but does not override any member functions

FINAL is used to decorate overridden virtual methods that are known (at compile time) to have no further subclass overrides. This allows the compiler to optimize call sites that operate on specific-enough pointer types to avoid the overhead of virtual dispatch.

If a subclass is known to never have any subclasses, the whole class can be marked FINAL, which is equivalent to making every overridden function in that class FINAL.

Example of FINAL:

class Human { 
public:
    virtual void dance();
};

class Swede : public Human { 
public:
    virtual void dance() OVERRIDE FINAL;
};

class Anders : public Swede {
public:
    virtual void dance() OVERRIDE { /* No. */ }
};

This code will fail with the following error:

teehee.cpp:15:18: error: declaration of ‘dance' overrides a 'final’ function

In other words, if Anders really wants to dance differently from other Swedes, you’ll have to remove the FINAL from Swede::dance().

What happens when we tell Anders to dance?

Human* man = getHuman();
man->dance(); // Virtual function call

Anders* ders = getAnders();
ders->dance(); // Inlined!

Because the compiler knows that “ders” is of type Anders, it doesn’t have to do a virtual function call, but can just inline the dance() implementation (or lack thereof) right there.

Pretty cool right? Giving the compiler this information means that it can generate smaller and faster code wherever we are using tighter pointer types.

Anyways, that’s pretty much it.

-Andreas

PS. Making a whole class FINAL looks like this:

class Countdown FINAL : public SwedishObject {

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20130726/34657ac6/attachment.html>


More information about the webkit-dev mailing list