【问题标题】:C++ workaroud virtual template methodC++ 变通的虚拟模板方法
【发布时间】:2021-06-16 00:15:48
【问题描述】:

我知道 C++ 中没有像虚拟模板方法这样的东西,但它似乎正是我所需要的。我可以使用任何解决方法吗?我很感谢您的任何建议。

我想通过 add 方法将实体添加到向量中,它需要是虚拟的,也是模板,如何避免这种情况?

#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>();
}

【问题讨论】:

  • 至少对您的实际示例有什么好处?无论如何,您的容器是基类的 shared_ptrs 的向量。对于您关于“准虚拟模板方法”的问题,实际上有一些解决方法,但我目前认为它们在这里并没有真正有用。
  • 是的,向量存储基类,但可以说 EntityDerived1 显示数字“1”,而 EntityDerived2 显示另一个数字...
  • 那么这可以通过您的 EntityBase 类的公共接口使用纯虚拟方法来描述。

标签: c++ templates inheritance virtual


【解决方案1】:

只需将add 设为以shared_ptr 为参数的常规虚函数

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);
    }
    // . . .

然后使用make_shared 调用它以获得所需的类型:

int main() {
    Engine  engine;

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

或者,您可以添加调用 make_shared 的模板化重载:

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

【讨论】:

    猜你喜欢
    • 2016-09-28
    • 2011-12-19
    • 2011-09-12
    • 2014-10-25
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多