Inheritance or Templates for Embedded application

Inheritance requires extra memory for virtual table. Templates can generate more code. When designing embedded application what approach should I select, or how to find proper mix.

Here is the example.

The application has a concept of a MessageReceiver - object that can receive messages from abstract source. I can have multiple implementations for MessageReceiver. MessageReceiver is injected to a particular object that works with messages.

Should I use templates or inheritance. What is more efficient?
Inheritance doesn't necessarily require a virtual table. Polymorphism does.

Dynamic polymorphism and static polymorphism solve different problems. Normally you want to do as much statically as possible, because the compiler is able to verify the types involved. You only use dynamic polymorphism if the type of an object depends on an unknown variable.
Your problem sounds like a use case for dynamic polymorphism. I'm unsure how templates could help here.
Thank you for your reply.

Here I will show 2 possible implementations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>

struct Message {
    int value;
};

class MessageReceiver {
public:
    virtual Message receive()= 0;
};

class ConcreteMessageReceiver : public MessageReceiver {
public:
    Message receive() override {
        return {};
    }
};


class ConcreteTemplateMessageReceiver {
public:
    Message receive() {
        return {};
    }
};


class ClientA {
    MessageReceiver *messageReceiver;
public:
    ClientA(MessageReceiver *messageReceiver) : messageReceiver(messageReceiver) {}

    void doSomething() {
        const Message &message = messageReceiver->receive();
    }
};

template<typename R>
class ClientB {
    R receiver;
public:
    ClientB(R receiver) : receiver(receiver) {}
    void doSomething() {
        Message message = receiver.receive();
    }
};


int main() {
    ConcreteMessageReceiver concreteMessageReceiver;
    ClientA clientA{&concreteMessageReceiver};
    clientA.doSomething();

    ConcreteTemplateMessageReceiver concreteTemplateMessageReceiver;
    ClientB<ConcreteTemplateMessageReceiver> clientB{concreteTemplateMessageReceiver};
    clientB.doSomething();
    return 0;
}


ClientA uses references and runtime inheritance, ClientB uses static polymorphism with templates. I have 2kB of SRAM and 32kB of program memory on my controller. I am trying to understand if using runtime inheritance will take significant amount of memory. Is it preferable to use templates for embedded development?

Or both approaches don't impact memory consumption?
Yeah, but ClientA has capabilities that ClientB doesn't. When you declared clientB you were forced to specify at compile time the type of the receiver you want, while with ClientA the type could be determined at run time, even though you didn't do it that way.

1
2
3
4
5
6
7
8
9
10
11
class ConcreteMessageReceiverA : public MessageReceiver {
public:
    Message receive() override;
};

class ConcreteMessageReceiverB : public MessageReceiver {
public:
    Message receive() override;
};

ClientA clientA(rand() % 2 ? new ConcreteMessageReceiverA : new ConcreteMessageReceiverB);

If you don't need this functionality then you should not be using dynamic polymorphism.
Cool that makes perfect sense. Thank you
another question. When code uses static polymorphism, is it a compiler who can inline template functions, therefore optimize the code or it is me, developer, who needs to explicitly inline functions where needed?
First of all, note that inline no longer has any effect on inlining behavior. Compilers may inline functions without inline and not inline functions with inline. Some compilers provide specific specifiers to force or disable inlining, but you should never specify inlining behavior unless you have very good reasons to do it.
That makes sense thank you for your help.
Topic archived. No new replies allowed.