Avoiding virtual features in an embedded target

I have class Playerone that plays data from a large block of memory, which consists of several identical pieces.

typedef char chunk_t[100];

typedef struct {
    chunk_t data[100]
} blockOfMemory_t;

The player himself could theoretically work for different layouts and data contents, so I would like to program it in a reusable way. To do this, I thought of something like this:

class Player {
public:
    Player() { ... }
    virtual ~Player() { ... }

    void play() 
    {
        for (int i = 0; i < getNumChunks(); i++)
        {
           if (chunkHasX(i) || chunkHasY(i))
               playChunk(i);
        }
    }

protected:
    virtual int getNumChunks() = 0;
    virtual bool chunkHasX(int chunkIndex) = 0;
    virtual bool chunkHasY(int chunkIndex) = 0;
    virtual void playChunk(int chunkIndex) = 0;
}

By inheriting this and realizing the data data from the child, I could achieve reuse.

ARM Cortex-M4, . . aproach, chunkHasX(..) ..

"" - ?

!

+2
2

, , . , , , .

CRTP

, (CRTP). , :

template<class Derived>
class Player {
public:
    void play() 
    {
        auto& derived = static_cast<Derived&>(*this);

        for (int i = 0; i < derived.getNumChunks(); i++)
        {
           if (derived.chunkHasX(i) || derived.chunkHasY(i))
               derived.playChunk(i);
        }
    }
};

class DerivedPlayer : public Player<DerivedPlayer> {
private:
  friend class Player<DerivedPlayer>;
  int getNumChunks();
  bool chunkHasX(int chunkIndex);
  bool chunkHasY(int chunkIndex);
  void playChunk(int chunkIndex);
};

int main() {
    DerivedPlayer p;
    p.play();
}

.

, , Player ChunkHolder, :

template<class ChunkHolder>
class Player {
private:
    ChunkHolder chunk_holder;
public:
    void play() 
    {   
        for (int i = 0; i < chunk_holder.getNumChunks(); i++)
        {
           if (chunk_holder.chunkHasX(i) || chunk_holder.chunkHasY(i))
               chunk_holder.playChunk(i);
        }
    }
};

class MyChunkHolder {
public:
  int getNumChunks();
  bool chunkHasX(int chunkIndex);
  bool chunkHasY(int chunkIndex);
  void playChunk(int chunkIndex);
};

int main() {
    Player<MyChunkHolder> p;
    p.play();
}

.

Update: , , . :

class IPlayer {
public:
  virtual ~IPlayer(){}
  virtual void play() = 0;
};

play():

template<class T>
class Player : IPlayer {
public:
    void play() override;
};

, , , , . Live demo CRTP .

+5

.

vtable, , :

ldr [r0,#8],r4 
blx r4

ldr #0x400025e5,r4
blx r4

( , , )

br #0x1035

, .

+2

Source: https://habr.com/ru/post/1681803/


All Articles