继承添加赋值操作,如何返回正确的类型?

时间:2012-10-11 07:33:43

标签: c++ inheritance copy-assignment

我有这个类来分解N维向量空间上的常见操作:

template <unsigned int N>
struct BaseVector
{
    float m_data[N];
    // Common operations like dot product, magnitude, test for unity, etc.
};

注意:我真的想要尽可能多地分解代码,以尽量减少文档和测试的数量。

现在,我派出了两个类:

// 3D geometric vectors
struct Vector3 : public BaseVector<3>
{
    Vector3 Cross(const Vector3& other);
    // ...
};

// Quaternions are a particular kind of vector space
struct Quaternion : public BaseVector<4>
{
    void Interpolate(const Quaternion& start, const Quaternion& end, ...);
    // ...
};

这些类对于加法和标量乘法(组件操作)的行为类似;所以,我想在基础矢量类中对operator+=()operator*=()进行分解。

我的问题是:如何返回正确类型的引用?

template <unsigned int N>
struct BaseVector
{
    ??? & operator+=(const BaseVector& other)
    {
        transform(m_data, m_data+N, other.m_data, m_data, plus<float>());
        return ???
    }
};

到目前为止我所有的想法(列在下面)并不令人满意,我希望得到一些建议,谢谢!


创意#1:使用C ++协变返回类型机制。但是,我必须在派生类中重载这些运算符 - 我是对的吗? (这意味着对我进行重复测试。)

创意#2:转到模板?

template <unsigned int N>
struct BaseVector
{
    template <typename T2>
    T2 & operator+=(const T2& other)
    {
        transform(...);
        return *this; // THIS IS WRONG! I'm trying to "upcast"
    }
};

创意#3:将代码分解为基本向量中的私有成员,但后来我必须在派生类中添加更多函数(以及更多要测试的东西)

template <unsigned int N>
struct BaseVector
{
private:
    void DoOperatorPlus(const BaseVector& other) { transform(...); }
};

struct Vector4 : public BaseVector<4>
{
    Vector4& operator+=(const Vector4& other)
    {
        DoOperatorPlus(other);
        return *this;
    }
};

1 个答案:

答案 0 :(得分:3)

您实际上可以尝试使用CRTP

我们的想法是为您的派生类的基类提供一个模板参数:

    template <unsigned int N, typename Derived>
    struct BaseVector
    {
        Derived & operator+=(const Derived& other)
        {
            transform(m_data, m_data+N, other.m_data, m_data, plus<float>());
            return static_cast<Derived&>(*this);
        }
    };

我对退货声明并不是100%肯定,但这应该会给你一个想法。