首页 > 解决方案 > 派生类可以从给定派生类模板化的模板化基类继承吗?这是个好主意吗?

问题描述

我想出了一个“模式”或其他任何名称,只是想问问专家这是否是一个好的设计,以及它可能存在哪些问题。在我的真实代码中,我有一些函数可以执行一些矩阵运算。我希望它们可以通过各种矩阵实现进行模板化,它们都应该具有相同的公共方法。假设强制执行这个通用接口,我想要一个抽象基类来规定接口。

代码片段显示了这个想法。定义接口的模板化基类。然后一些派生类都实现了相同的功能(请注意,它们是被迫的,否则它们将无法实例化)。我使用的奇怪的是派生类定义中 A 的模板参数是派生类本身,不确定这是否是个好主意?

请注意,我知道 B、C 和 D 类实际上不是从同一个类派生的,但这不是我需要的。我只想为所有派生类强制执行一个通用接口,以明确应该实现什么。

我也知道 AddTwoWhatever 函数可以很容易地与其他一些与基类 A 无关的模板参数一起使用,但我也很好。我不是试图实现模板限制,只是为 A 行为的新实现提供指导。

总而言之,我有附件代码中显示的设计,我想问一下这是否是一个好主意,如果它可以工作,它可能存在哪些问题?

template <class T>
class A
{
public:
    virtual void Add(const T& aOther) = 0;
    virtual void PrintValue() const = 0;
};

class B : public A<B>
{
private:
    int mValInt;

public:
    B(int aVal) : mValInt(aVal) { }
    virtual void Add(const B& aOther) override
    {
        mValInt += aOther.mValInt;
    }
    virtual void PrintValue() const override
    {
        std::cout << mValInt << std::endl;
    }
};

class C : public A<C>
{
private:
    double mValDouble;
public:
    C(double aVal) : mValDouble(aVal) { }
    virtual void Add(const C& aOther) override
    {
        mValDouble += aOther.mValDouble;
    }
    virtual void PrintValue() const override
    {
        std::cout << mValDouble<< std::endl;
    }
};

class D : public A<D>
{
private:
    float mValFloat;
};

template <class T>
void AddTwoWhatever(T aFirst, T aSecond)
{
    T aResult(0);

    aResult.Add(aFirst);
    aResult.Add(aSecond);

    aResult.PrintValue();
}

int main(int argc, char **argv) 
{
    B b1(10);

    B b2(11);

    b1.Add(b2);

    b1.PrintValue();

    C c1(13.9);

    C c2(16.3);

    // b1.Add(c1); // gives compile time error as I want it to

    AddTwoWhatever(b1, b2);
    AddTwoWhatever(c1, c2);

    // AddTwoWhatever(b1, c2); // again, gives error as intended

    // D d; // gives compile time error because D is abstract (not implementing A), again, something that I want, enforce the A implementation

    return 0;
}

标签: c++templatesinheritanceinterface

解决方案


推荐阅读