2 votes

Méthode modèle virtuelle de travail en C++

Je sais qu'il n'y a rien de tel que la méthode template virtuelle en C++, mais il semble que ce soit exactement ce dont j'ai besoin. Y a-t-il une solution de rechange que je puisse utiliser ? Je suis reconnaissant pour toute suggestion.

J'aimerais ajouter des entités à un vecteur par une méthode add, qui doit être virtuelle et également template, comment éviter cela ?

#include <iostream>
#include <vector>

class EntityBase {
public:
};

class EntityDerived1 : public EntityBase {
public:
};

class EntityDerived2 : public EntityBase {
public:
};

class ContainerBase {
public:
    template<typename T>
    virtual void add() = 0; // i know this is not allowed!!!
};

class ContainerConcrete : public ContainerBase {
public:
    template<typename T>
    void add() override {   // i know this is not allowed!!!
        data.push_back(std::make_shared<T>());
    }

    void doSecretStuffWithDataHere() {
        //  ...
    }

private:
    std::vector<std::shared_ptr<EntityBase>>    data;
};

class Engine {
public:
    Engine() :
        container(std::make_shared<ContainerConcrete>())
    {}

    ContainerBase& getContainer() {
        auto rawPointer = container.get();
        return *container;
    }

private:
    std::shared_ptr<ContainerConcrete> container;
};

int main() {
    Engine  engine;

    ContainerBase& container = engine.getContainer();
    container.add<EntityDerived1>();
    container.add<EntityDerived2>();
}

3voto

rustyx Points 2722

Il suffit de faire add une fonction virtuelle normale qui prend shared_ptr comme paramètre

class ContainerBase {
public:
    virtual void add(std::shared_ptr<EntityBase>) = 0;
};

class ContainerConcrete : public ContainerBase {
public:
    void add(std::shared_ptr<EntityBase> p) override {
        data.push_back(p);
    }
    // . . .

Puis l'invoquer avec make_shared pour le type souhaité :

int main() {
    Engine  engine;

    ContainerBase& container = engine.getContainer();
    container.add(std::make_shared<EntityDerived1>());
    container.add(std::make_shared<EntityDerived2>());
}

Vous pouvez également ajouter une surcharge modélisée qui invoque make_shared :

    virtual void add(std::shared_ptr<EntityBase>) = 0;
    template<typename T>
    void add() {
        add(std::make_shared<T>());
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X