diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 2c988279f6..dbcae0b944 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -1249,6 +1249,7 @@ public: ~Ptr(); //! copy constructor. Copies the members and calls addref() Ptr(const Ptr& ptr); + template Ptr(const Ptr<_Tp2>& ptr); //! copy operator. Calls ptr.addref() and release() before copying the members Ptr& operator = (const Ptr& ptr); //! increments the reference counter diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 1f96722fc6..fe9caa41ba 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -2642,14 +2642,35 @@ template inline Ptr<_Tp>::operator const _Tp*() const { return obj template inline bool Ptr<_Tp>::empty() const { return obj == 0; } +template template Ptr<_Tp>::Ptr(const Ptr<_Tp2>& p) + : obj(0), refcount(0) +{ + if (p.empty()) + return; + + _Tp* p_casted = dynamic_cast<_Tp*>(p.obj); + if (!p_casted) + return; + + obj = p_casted; + refcount = p.refcount; + addref(); +} + template template inline Ptr<_Tp2> Ptr<_Tp>::ptr() { Ptr<_Tp2> p; if( !obj ) return p; + + _Tp2* obj_casted = dynamic_cast<_Tp2*>(obj); + if (!obj_casted) + return p; + if( refcount ) CV_XADD(refcount, 1); - p.obj = dynamic_cast<_Tp2*>(obj); + + p.obj = obj_casted; p.refcount = refcount; return p; } @@ -2659,9 +2680,15 @@ template template inline const Ptr<_Tp2> Ptr<_Tp>:: Ptr<_Tp2> p; if( !obj ) return p; + + _Tp2* obj_casted = dynamic_cast<_Tp2*>(obj); + if (!obj_casted) + return p; + if( refcount ) CV_XADD(refcount, 1); - p.obj = dynamic_cast<_Tp2*>(obj); + + p.obj = obj_casted; p.refcount = refcount; return p; }