c++ - 在 C++ 接口(interface)中声明模板函数?

标签 c++ unit-testing templates interface

为了演示,假设我有一些动物类,每个都派生自“动物”类,每个都“知道”它们是什么类型,并且每个都具有某种独特的能力:

enum class animal_type { antelope, bear, cat };

class animal
{
};

class antelope : public animal
{
public:
    static const animal_type type = animal_type::antelope;
    void run() { std::cout << "antelope runs\n"; };
};

class bear : public animal
{
public:
    static const animal_type type = animal_type::bear;
    void roar() { std::cout << "bear roars\n"; };
};

class cat : public animal
{
public:
    static const animal_type type = animal_type::cat;
    void meow() { std::cout << "cat meows\n"; };
};

现在,我希望能够根据动物的类型检索动物:

class animal_getter
{
public:
    animal& get(animal_type t)
    {
        static antelope s_antelope;
        static bear s_bear;
        static cat s_cat;

        switch (t)
        {
            case animal_type::antelope:
                return s_antelope;

            case animal_type::bear:
                return s_bear;

            case animal_type::cat:
                return s_cat;
        }
    }
};

最后,最好返回动物的实际类型,使调用语法更好:

template<typename T>
T& get()
{
    return static_cast<T&>(get(T::type));
}

现在我可以这样写了:

animal_getter ag;
ag.get<antelope>().run();

而不是罗嗦:

animal_getter ag;
static_cast<antelope&>(ag.get(animal_type::antelope)).run();

我希望这没有什么太不合理的地方。但是现在我希望能够对动物进行单元测试,所以理想情况下可以伪造 animal_getter 类(想象一下实际实现访问数据库或单元测试中不需要的东西,因此是假的) .因此,最好为“动物 setter/getter ”类定义一个接口(interface),然后创建一个实现该接口(interface)的假对象。而问题来了,这个接口(interface)能不能写?这不会编译:

struct IAnimalGetter
{
    virtual template<typename T> T& get() = 0;
};

是否有可能拯救这个想法,或者为了定义包含它们的接口(interface),模板函数永远不会被声明为虚拟的?

如果这个想法是行不通的,那么它是从什么时候开始出错的? 是在编写自己进行转换的模板函数时吗?我是否应该在返回动物对象的地方停下来,然后让调用者负责转换?

最佳答案

虚拟模板函数是不允许的,但是你的模板函数没有逻辑,所以在这种情况下我会使用:

struct IAnimalGetter
{
    virtual animal& get(animal_type t) = 0;

    template<typename T>
    T& get()
    {
      return static_cast<T&>(get(T::type));
    }
};

和:

class animal_getter : public IAnimalGetter
{
public:
    animal& get(animal_type t)
    {
        // implementation
    }
};

class mock_animal_getter : public IAnimalGetter
{
public:
    animal& get(animal_type t)
    {
        // mock implementation
    }
};

关于c++ - 在 C++ 接口(interface)中声明模板函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45480502/

相关文章:

Mac上的c++开发

c++ - 传递 constexpr 函数以在编译时使用

c++ - OpenGL渲染器类设计: flexible and simple?

c++ - 为什么 std::adressof() 在无效输入时表现如此?

unit-testing - MsTest 不支持在测试基类中定义 TestMethod 吗?

c++ - 类成员通过回调函数调用函数模板

node.js - 在 ElectronJS 中使用 Electron-Remote 开 Jest 测试 React 组件

unit-testing - 这种依赖注入(inject)的设计容易理解吗?

c++ - 模板元编程时struct和class的区别

c++ - 我可以将类模板添加到元组吗?