mercredi 26 octobre 2016

Abstract class as an interface, without the vtable

I'd like to make an abstract class that defines some methods of a class. Some of these should be implemented by the base class (Base), some should be defined in Base but overwritten by Derived and others should be pure virtual in Base to force definition in Derived.

This is of course what abstract classes are for. However, my application will only ever use the Derived object directly. Because of this, the compiler should know at compile-time exactly which methods are to be used.

Now, because this code will run on a microcontroller with very limited RAM, I'm keen to avoid actually using a virtual class with the vtable this entails. From my testing it seems that the compiler is smart enough to not make a vtable unless it has to, at least in some circumstances. However I've been told to never trust the compiler: is it possible to make this a required condition of compilation?

Here are some code examples:

Classes

class Base {
  public:
    Base() {}
    virtual ~Base() {};

    virtual int thisMustBeDefined() = 0;
    virtual int thisCouldBeOverwritten() { return 10; }
    int thisWillBeUsedAsIs() { return 999; }
};

class Derived : public Base {
  public:
    Derived() {}
    ~Derived() {}

    int thisMustBeDefined() { return 11; }

};

No vtable

This has no vtable and is what I want

int main() {
  Derived d;
  d.thisMustBeDefined();
}

Yes vtable 1

As a result of my sloppy coding, I've mistakenly forced the compiler to use polymorphism and therefore to require a vtable. How can I make this case throw an error?

int main() {
  Base * d;
  d = new Derived();
  d->thisMustBeDefined();
}

Yes vtable 2

Here I've not refered to the class "Base" at any point, so the compiler should know that all the methods are pre-determined at compile time. However it still creates a vtable. This is another example of why I want to be able to detect this with a compile error.

int main() {
  Derived * d;
  d = new Derived();
  d->thisMustBeDefined();
}

In other words, I want it to be a compiler error if I write code that results in the compiler producing a vtable for my classes, i.e. uses polymorphism.

Aucun commentaire:

Enregistrer un commentaire