当前位置: 首页 > 知识库问答 >
问题:

C++workaroud虚拟模板方法

郭均
2023-03-14

我知道在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>();
}

共有1个答案

邵子平
2023-03-14

只需使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>());
    }
 类似资料:
  • 相比之下,Java确实允许虚拟泛型方法。这里也清楚了如何实现:Java泛型在运行时被删除,因此泛型方法是运行时的常用方法,因此不需要修改。 但是现在到了C#。C#确实有具体化的泛型。对于具体化泛型,特别是当使用值类型作为类型参数时,泛型方法必须有不同的版本。但是我们遇到了与C++相同的问题:每当对泛型方法进行新的实例化时,我们都需要修改vtable。 我对C#的内部工作没有太深的了解,所以我的直觉

  • 当部署模板验证失败时,我的代码中出现了一个错误:行105和列9处的模板资源myVMć无效:模板函数reourceId无效。使用详情请看https://aka.ms/arm-template-expressions。使用详情请见https://aka.ms/arm-template-expressions。(代码:InvalidTemboard)。 我已经尝试解决这个错误但我不会 } 结果是,这将使

  • 本文向大家介绍C#处理datagridview虚拟模式的方法,包括了C#处理datagridview虚拟模式的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#处理datagridview虚拟模式的方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的C#程序设计有所帮助。

  • 我对虚拟函数感到困惑。有人告诉我,父类中的虚拟意味着我可以在子类中覆盖它。但是,如果我省略父类中的虚拟,我仍然可以覆盖它。

  • 从派生,并使用自定义结构对其进行专门化。也重载。然而,这才是问题的根源。如果我尝试编译它,我会得到: 显然,没有运算符“+”。但这是我的困惑…编译器被要求实现,因为这是继承的内容。但是,我从不使用或调用。那么编译器应该尝试生成这个基类函数吗?