c – 动态转换“this”作为返回值是否可以?
这更像是一个设计问题.
我有一个模板类,我想根据模板类型添加额外的方法.为了实践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方法对于那些人来说更为可取. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |