修正了算术类中的循环依赖

Fix circular dependency in arithmetic class

本文关键字:循环 依赖      更新时间:2023-10-16

我有一组实现奇怪的重复出现的模板模式的类。但是,诀窍在于基类需要返回子类的实例。下面是一个例子:

template <typename SubType>
class ArithmeticBase
{
public:
    template <typename OtherType>
    const Addition operator+(const OtherType &other)
        {return Addition(get_subclass(), other);}
    // ...
    // Operators for subtraction, multiplication, division, ...
private:
    const SubType &get_subclass() const
        {return *static_cast<const SubType*>(this);}
};
template <typename OperatorType1, typename OperatorType2>
class Addition : ArithmeticBase<Addition<OperatorType1, OperatorType2>>
{
public:
    Addition(const OperatorType1 &op1, const OperatorType2 &op2)
        : op1(op1)
        , op2(op2)
    {}
private:
    const OperatorType1 &op1;
    const OperatorType2 &op2;
};
// ...
// Additional classes for subtraction, multiplication, division, ...

编译失败,因为Addition类在ArithmeticBase类中使用之前没有定义:

arithmetic.cpp:6:8: error: unknown type name 'Addition'
        const Addition operator+(const OtherType &other)
              ^

如何解决这个问题?

可以在基类之前向前声明Addition

template <typename OperatorType1, typename OperatorType2>
class Addition;
template <typename SubType>
class ArithmeticBase
{
...
};

这允许编译器在定义类型Addition之前知道它存在。

或者使用在Addition之后声明的非成员形式:

template <typename OperatorType1, typename OperatorType2>
class Addition;
template <typename SubType>
class ArithmeticBase
{
public:
     template <typename OneType, typename OtherType>
     friend const Addition<OneType, OtherType> operator+(const ArithmeticBase<OneType>& one, const OtherType &other);
private:
    const SubType &get_subclass() const
    {
        return *static_cast<const SubType*>(this);
    }
};
class ArithmeticType : public ArithmeticBase < ArithmeticType > {};
template <typename OperatorType1, typename OperatorType2>
class Addition : ArithmeticBase<Addition<OperatorType1, OperatorType2>>
{
public:
    Addition(const OperatorType1 &op1, const OperatorType2 &op2)
        : op1(op1)
        , op2(op2)
    {}
private:
    const OperatorType1 &op1;
    const OperatorType2 &op2;
};

template <typename OneType, typename OtherType>
const Addition<OneType, OtherType> operator+(const ArithmeticBase<OneType>& one, const OtherType &other)
{
    return Addition<OneType, OtherType>(one.get_subclass(), other);
}
int main()
{
    ArithmeticType a, b;
    a + b;
}

除了向前声明Addition类(如bhzag的回答所示)之外,还需要将operator+的定义移动到add类定义之后。否则,您将在下一行得到一个错误。

确保定义在头文件中。如果不是,您将得到链接器错误。