加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 动态转换“this”作为返回值是否可以?

发布时间:2020-12-16 10:22:28 所属栏目:百科 来源:网络整理
导读:这更像是一个设计问题. 我有一个模板类,我想根据模板类型添加额外的方法.为了实践DRY原则,我提出了这种模式(故意省略了定义): template class Tclass BaseVector: public boost::arrayT,3{protected: BaseVectorT(const T x,const T y,const T z);public: b
这更像是一个设计问题.

我有一个模板类,我想根据模板类型添加额外的方法.为了实践DRY原则,我提出了这种模式(故意省略了定义):

template <class T>
class BaseVector: public boost::array<T,3>
{
protected:
    BaseVector<T>(const T x,const T y,const T z);
public:
    bool operator == (const Vector<T> &other) const;
    Vector<T> operator + (const Vector<T> &other) const;    
    Vector<T> operator - (const Vector<T> &other) const;
    Vector<T> &operator += (const Vector<T> &other)
    {
        (*this)[0] += other[0];
        (*this)[1] += other[1];
        (*this)[2] += other[2];

        return *dynamic_cast<Vector<T> * const>(this);
    }

    virtual ~BaseVector<T>()
    {
    }
}

template <class T>
class Vector : public BaseVector<T>
{
public:
    Vector<T>(const T x,const T z)
    : BaseVector<T>(x,y,z)
    {
    }
};

template <>
class Vector<double> : public BaseVector<double>
{
public:
    Vector<double>(const double x,const double y,const double z);
    Vector<double>(const Vector<int> &other);
    double norm() const;
};

我打算将BaseVector仅仅作为一个实现细节.这有效,但我担心operator =.我的问题是:这个指针的动态转换是代码味道吗?有没有更好的方法来实现我想要做的事情(避免代码重复,以及用户代码中不必要的演员表)?或者我是安全的,因为BaseVector构造函数是私有的吗?

编辑:

对不起,是的,我有虚拟dtor,但我忘了粘贴它,没有它,代码不能编译.

解决方法

我建议您考虑另一种方法(请注意,在下面的示例中,我已将代码简化为演示替代方法所需的最低限度).

首先,考虑奇怪的重复模板参数(CRTP):

template <typename T,typename DerivedVector>
struct BaseVector
{
    DerivedVector& operator+=(DerivedVector const& other)
    {
        return static_cast<DerivedVector&>(*this);
    }
};

template <typename T>
struct Vector : BaseVector<T,Vector<T>>
{
};

由于您始终知道派生类型是什么,因此static_cast就足够了.如果Vector< T>是唯一一个基数为BaseVector< T>的类.如果你保证T参数总是相同的,那么严格来说,CRTP参数是不必要的:你总是知道派生类型是什么,所以static_cast是安全的.

或者,考虑运算符不必是成员函数,因此您可以声明非成员运算符函数模板:

template <typename T,typename DerivedVector>
struct BaseVector
{
};

template <typename T>
struct Vector : BaseVector<T,Vector<T>>
{
};

template <typename T>
Vector<T>& operator+=(Vector<T>& self,Vector<T> const& other)
{
    return self;
}

虽然后者对于操作符来说是优选的,但它不适用于普通的非运算符成员功能,因此CRTP方法对于那些人来说更为可取.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读