![Copy智能指针不需要虚拟副本构造函数 Copy智能指针不需要虚拟副本构造函数]()
本文介绍了Deep Copy智能指针不需要虚拟副本构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 几天前,我发布了一个深拷贝指针的代码, 不需要指针对象有一个虚拟拷贝构造函数。 我需要帮助检查它是异常安全和异常 中立/ 我得到了Bux的回复,他的智能指针代码少得多 代码行 和更清洁的设计,不像我的那样过度设计。 http://groups.google.co.uk/group/com .. .e5c18bc6bb5c7e 然而,该代码有一个可能的扩展: ''权衡是copy_ptr< Baseand copy_ptr< Derivedare 无关'' Kai-Uwe Bux 我想我已设法实现此扩展,所以我发布了我的代码 这里还有一个ex.c的main.cpp b)扩展名。 任何关于我滥用语言的评论都非常欢迎 ------------- -------------------------------------------------- ----------------------------------------------- < smart_ptr_policies.h> #ifndef SMART_POINTER_POLICIES_HEADER #define SMART_POINTER_POLICIES_HEADER #include< algorithm> #include< boost / utility.hpp> #include< boost / type_traits.hpp> // http://groups.google.co。 uk / group / com ... hread / thread / b ... 模板< class DerivedClass> void * Buxclone(const void * theOtherPtr){ 返回新的DerivedClass(* static_cast< const DerivedClass *>(theOtherPtr)); } 模板< class BaseClass> struct BuxWrappedPointer { 模板< class T> 朋友结构BuxWrappedPointer; BuxWrappedPointer():raw_pointer(0), theCloner(0){} 模板< class DerivedClass> BuxWrappedPointer(DerivedClass * ptr):raw_pointer(ptr), theCloner(& Buxclone< DerivedClass>){} BuxWrappedPointer(const BuxWrappedPointer& theOther): theCloner(theOther.theCloner), raw_pointer(theOther.clone(theOther.raw_pointer)){} 模板< class MiddleBase> BuxWrappedPointer(const BuxWrappedPointer< MiddleBase> & theMiddleBase, typename boost :: enable_if< boost :: is_base_of< BaseClass,Middl eBase>,MiddleBase> :: type * pp = 0): theCloner(theMiddleBase.theCloner), raw_pointer(static_cast< BaseClass *> (theMiddleBase.theCloner(static_cast< const BaseClass *>(theMiddleBase) .raw_pointer)))){} BuxWrappedPointer< BaseClass& operator =(const BuxWrappedPointer< BaseClass& theOther) { BuxWrappedPointer< BaseClasstemp(theOther); std :: swap(temp.raw_pointer,raw_pointer); 返回* this; } BaseClass * raw_pointer; ~BuxWrappedPointer(){delete raw_pointer;} private: BaseClass * clone(const BaseClass * theSource)const { return static_cast< BaseClass *>(theCloner(static_cast< cons t BaseClass *>(theSource))); } typedef void *(* clone _)(const void *); clone_ theCloner; }; #endif -------------------------------------------------- -------------------------------------------------- ---------- < smart_ptr.h> #ifndef SMART_POINTER__HEADER #define SMART_POINTER__HEADER #include" smart_ptr_policies.h" 模板< 类BaseClass, 模板< classclass CLONE_POLICY class smart_ptr { public: typedef typename boost :: remove_const< BaseClass> :: type non_const_base ; 模板< class T,模板< classclass CLONE_POLICY> 朋友类smart_ptr; 模板< ;类DerivedClass> smart_ptr(DerivedClass * theDerivedPointer _):theWrappedPointer(theDerivedPo inter _){} smart_ptr(const smart_ptr< ; non_const_base,CLONE_POLICY>& theOtherSmart_ptr): theWrappedPointer(theOtherSmart_ptr.theWrappedPoin ter){} smart_ptr(const smart_ptr< const non_const_base,CLONE_POLICY>& theOtherSmart_ptr): theWrappedPointer(theOtherSmart_ptr.theWrappedPoin ter){} 模板< ;类T> smart_ptr(const smart_ptr< T,CLONE_POLICY>& theOtherSmart_ptr, typename boost :: enable_if< boost :: is_base_of< non_con st_base,typename boost :: remove_const< T> :: type>,T> :: type * pp = 0): theWrappedPointer(theOtherSmart_ptr.theWrappedPoin ter){ } smart_ptr(){} BaseClass * operator->()const {return theWrappedPointer .raw_pointer;} 虚拟~smart_ptr(){} 私人: smart_ptr& operator =(const BaseClass * ptr); CLONE_POLICY< non_const_basetheWrappedPointer; }; #endif ----------------------------------------------- -------------------------------------------------- ------------- < main.cpp> #include< vector> #include< ; iostream> #include< cctype> #include" smart_ptr.h" using namespace std ; class Base { public: Base():ch(''*''){ Count ++; } Base(const Base&):ch(''*''){ Count ++; } 虚拟char show(){ 返回ch; } 虚拟~Base (){Count--;} virtual void v()const = 0; static unsigned long Count; private: char ch; }; unsigned long Base :: Count(0); / //这会给我们很多衍生物ed class template< char ch_> class派生:public Base { public: Derived() :ch(ch _){ Count ++; } 派生(const Derived< ch_>&):ch(ch _){ 点数++; } 虚拟字符显示(){ 返回ch; } virtual~派生(){Count--;} virtual void v()const {} static unsigned long Count; 私人: char ch; }; 模板< char ch_> unsigned long派生< ch_> :: Count(0); 模板< char ch_> 类DerivedSquared:public Derived< ch_ { public: DerivedSquared():ch(std :: tolower(ch _)){ Count ++; } DerivedSquared(const DerivedSquared< ch_>&):ch(std :: tolower(ch _)){ Count ++; } 虚拟char show(){return ch;} virtual~DerivedSquared(){Coun t--;} virtual void v()const {} static unsigned long Count; private: char ch; }; 模板< char ch_> unsigned long DerivedSquared< ch_> :: Count( 0); int main(){ smart_ptr< Derived<''B''>,BuxWrappedPointertheDPA(新的 DerivedSquared<''B''>); cout<< theDPA-> show(); smart_ptr< Base,BuxWrappedPointertheDPA2(theDPA); cout<< theDPA2-> show(); } ------------------------- -------------------------------------------------- ---------------------------------------------- NSC 解决方案 为什么你需要这样的野兽?即什么是要求和用例? 这有点难以阅读。 http://groups.google.co.uk/group/com...e5c18bc6bb5c7e 多么巧合,你的帖子也促使我重新思考这一点。我看来 我们得出了非常相似的结论(见下文)。 一般评论:你的行太长了。 *> BaseClass 哦,小伙子,你很精通!然而,我并没有完全看到所有 这个enable_if< ......东西在为你做。如果你只是为了获得 正确的编译错误 copy_ptr< Base b_ptr = copy_ptr< NotDerived>(new not Derived()); 然后,我认为,有更简单的方法去做(见下文)。但是我 可能会遗漏一些东西。 class smart_ptr { public: **************** typedef typename boost :: remove_const< BaseClass>: :类型 **************** non_const_base; ********** ******模板< class T,模板< classclass CLONE_POLICY> ****************朋友类smart_ptr; g ++给我一个错误,上面说的是 CLONE_POLICY的声明会影响模板参数。 再次,我发现增强的东西令人困惑。什么设计规格需要使用non_const_base和remove_const ? 我发现 smart_ptr< inti_ptr(new int(5)); cout<< * i_ptr<< ''\ n''; 给了我一个错误。你应该添加运算符*。 我在非基于策略的版本上做了一点工作,让copy_ptr< Baseand copy_ptr< Derivedbehave as desired。我还使用非多态基类添加了编译时间检查 。这可能是矫枉过正。 (或者,可以考虑添加一个删除函数,无论如何都会使用正确的析构函数。) #include< algorithm // std :: swap template< typename T> struct non_polymorphic_class_error { enum { trigger = sizeof(dynamic_cast< void *>(static_cast< T *> (0))) }; }; //克隆功能: // =================== 模板< typename T> void * clone(void * ptr){ return(ptr == 0?0 :static_cast< void * > (新T(*(static_cast< T *>(ptr))))); } // copy_ptr: // ============= 模板< typename T> class copy_ptr { friend void swap(copy_ptr< T& p,copy_ptr< T& q){ std :: swap(p.raw_ptr,q.raw_ptr); std :: swap(p.clone_fct,q.clone_fct); } 模板< typename D> 朋友类copy_ptr; / * 这个想法是除了指针之外,我们还需要 a指向_appropriate_克隆功能。 * / T * raw_ptr; void *(* clone_fct)(void *); public: copy_ptr(T * ptr = 0) : raw_ptr(ptr) ,clone_fct(clone< T) {} template< typename D> copy_ptr(D * ptr) :raw_ptr(ptr) ,clone_fct(clone< D) { non_polymorphic_class_error< Td2; } //复制构造克隆: copy_ptr(copy_ptr const& other) :raw_ptr(static_cast< T *>(other.clone_fct(other.raw_ptr))) ,clone_fct(其他.clone_fct) {} 模板< typename D> copy_ptr(copy_ptr< Dconst& other) :raw_ptr(static_cast< D *>(other.clone_fct(other.raw_ptr))) ,clone_fct(other.clone_fct) { non_polymorphic_class_error< Td2; } //销毁释放了指针对象 ~copy_ptr(无效){ 删除(raw_ptr); } //赋值减少到复制结构 //(为了正确性和异常安全性): copy_ptr& operator =(copy_ptr const& other){ copy_ptr dummy(other); swap(* this,dummy); return( * this); } 模板< typename D> copy_ptr& operator =(copy_ptr< Dconst& other){ copy_ptr dummy(other); swap(* this,dummy); return (* this); } T const * operator-(void)const { return(raw_ptr); } T * operator-(void){ return(raw_ptr); } T const& operator *(void)const { return(*(this-> operator->())); } T& operator *(void){ return(*(this-> operator->())); } }; // copy_ptr< T> 请让我知道你的想法。 Best Kai- Uwe Bux http://groups.google.co.uk/group/com...e 5c18bc6bb5c7e 多么巧合,你的帖子也促使我重新思考。我看来 我们得出了非常相似的结论(见下文)。 一般评论:你的行太长了。 我为此道歉线条的长度,我认为我的问题是2倍。 首先,我不是专业的开发人员 我从来没有真正学过代码演示的好风格,但是我认为假设像doxygen这样的工具可以让你无比借口。其次,我认为 粘贴出了问题。 *> BaseClass 哦,小伙子,你很精通!然而,我并没有完全看到所有 这个enable_if< ......东西在为你做。 If it is just to get the right compiler errors if you do copy_ptr< Base b_ptr = copy_ptr< NotDerived >( new not Derived() ); then, I think, there are simpler means of going about it (see below). But I might be missing something here. re enable_if from the boost website The enable_if family of templates is a set of tools to allow a function template or a class template specialization to include or exclude itself from a set of matching functions or specializations based on properties of its template arguments. For example, one can define function templates that are only enabled for, and thus only match, an arbitrary set of types defined by a traits class. The enable_if templates can also be applied to enable class template specializations. So I am only enabling BuxWrappedPointer(const BuxWrappedPointer<MiddleBase> &theMiddleBase) when MiddleBase is derived FROM Base. This allows : clone_ptr<MiddleBasetheMiddleClass_ptr(new Derived); clone_ptr<BasetheBaseClass_ptr (theMiddleClass_ptr); // casting up the hierachy should be allowed but disallows everything else including clone_ptr<BasetheBaseClass_ptr (new Derived); clone_ptr<MiddleBasetheMiddleBaseClass_ptr (theMiddleClass_ptr); // casting down the hierachy should NOT be allowed class smart_ptr { public: typedef typename boost::remove_const<BaseClass>::type non_const_base; template<class T,template <classclass CLONE_POLICY > friend class smart_ptr; g++ gives me an error for the above saying that the declaration of CLONE_POLICY shadows the template parameter. Why is this destructor virtual? Again, I find the boost stuff confusing. What design specs necessitate the use of non_const_base and remove_const? This non_const_base gives me ’’type’’ from ’’const type’’ So this allows me to do : copy_ptr<BasethePtr(new Derived); copy_ptr<const BasetheConstPtr(thePtr); Of course this may not be so important for deep copy but may be useful for other policies. But I still want the Policy class to be template on Base, even if the smart_ptr is templated on Base or const Base, in some sense they are the same. The line template<class T> smart_ptr(const smart_ptr<T,CLONE_POLICY>& should be something like template<class T, template <classclass OTHER_CLONE_POLICY> smart_ptr(const smart_ptr<T,OTHER_CLONE_POLICY>& sorry, I use both Linux gcc and msvc, and I happend to be using msvc at that moment, and it did not complain. Again I am using the boost template stuff ONLY when T is derived FROM Base, for same reasons as above. But I m ripping of the const of them before I compare. That is BaseClass = Base T = MiddleBase This is ok BaseClass = const Base T = MiddleBase This is ok BaseClass = Base T = const MiddleBase This is ok BaseClass = const Base T = const MiddleBase This is ok I found that smart_ptr<inti_ptr ( new int ( 5 ) ); cout << *i_ptr << ’’\n’’; gives me an error. You should add operator*. I completely agree, I should have posted a more complete class. But I just wanted to show my extension to your trick leaving out the other details. I intend to add other members too, such as interoperability with auto_ptr etc I forbid myslef from using dynamic_cast, but I would have to try to remeber the reasons why. But I do have a question. Isn’’t it true that dynamic_cast happens at runtime and therefore we have a overhead, whereas static_cast takes place at compile time, so we don’’t. I think the boost is_base combined with boost enable_if lets us ’’error check’’ at compile time. I by no means am ’’boost savy’’ I didn’’t even know about is_basr until a few days ago. Its just that I find some real magical bits of functionality there, its a waste of time trying to re-code some of it, especially when the boost coders are in a far superior league to of programmers to me. Also I prefer to do as much as possible at compile time than at runtime. N PS I think my first ever use of is_base was to write this class. A few days a ago I posted my code for a deep copy pointer whichdoesn''t require the pointee object to have a virtual copy constructor.I need help with checking that it was exception safe and exceptionneutral/I got a reply from Bux with his code for a smart pointer with far fewerlines of codeand more cleaner design, not over engineered like mine. http://groups.google.co.uk/group/com...e5c18bc6bb5c7eHowever there was one possible extension to that code :''The trade-off is that copy_ptr<Baseand copy_ptr<Derivedareunrelated ''Kai-Uwe BuxI think I have managed to implement this extension, so I post my codehere along with a main.cpp that exhibists the extension.Any comments about my abuse of the language would be more than welcome--------------------------------------------------------------------------------------------------------------<smart_ptr_policies.h>#ifndef SMART_POINTER_POLICIES_HEADER#define SMART_POINTER_POLICIES_HEADER#include<algorithm>#include<boost/utility.hpp>#include<boost/type_traits.hpp>// http://groups.google.co.uk/group/com...hread/thread/b...template<class DerivedClass>void * Buxclone(const void *theOtherPtr){return new DerivedClass(*static_cast<constDerivedClass*>(theOtherPtr));}template<class BaseClass>struct BuxWrappedPointer {template<class T>friend struct BuxWrappedPointer;BuxWrappedPointer():raw_pointer(0),theCloner(0){}template<class DerivedClass>BuxWrappedPointer(DerivedClass * ptr):raw_pointer(ptr),theCloner(&Buxclone<DerivedClass>){}BuxWrappedPointer(const BuxWrappedPointer &theOther):theCloner(theOther.theCloner),raw_pointer(theOther.clone(theOther.raw_pointer)){ }template<class MiddleBase>BuxWrappedPointer(const BuxWrappedPointer<MiddleBase>&theMiddleBase,typenameboost::enable_if<boost::is_base_of<BaseClass,Middl eBase>,MiddleBase>::type*pp=0):theCloner(theMiddleBase.theCloner),raw_pointer(static_cast<BaseClass *>(theMiddleBase.theCloner(static_cast<const BaseClass*>(theMiddleBase.raw_pointer)))){}BuxWrappedPointer<BaseClass& operator=(constBuxWrappedPointer<BaseClass&theOther){BuxWrappedPointer<BaseClasstemp(theOther);std::swap(temp.raw_pointer,raw_pointer);return *this;}BaseClass * raw_pointer;~BuxWrappedPointer(){delete raw_pointer;}private:BaseClass *clone(const BaseClass * theSource)const{return static_cast<BaseClass*>(theCloner(static_cast<cons tBaseClass*>(theSource)));}typedef void * (*clone_)(const void *);clone_ theCloner;};#endif--------------------------------------------------------------------------------------------------------------<smart_ptr.h>#ifndef SMART_POINTER__HEADER#define SMART_POINTER__HEADER#include"smart_ptr_policies.h"template<class BaseClass,template <classclass CLONE_POLICYclass smart_ptr {public:typedef typename boost::remove_const<BaseClass>::type non_const_base;template<class T,template <classclass CLONE_POLICY >friend class smart_ptr;template<class DerivedClass>smart_ptr(DerivedClass *theDerivedPointer_):theWrappedPointer(theDerivedPo inter_){}smart_ptr(const smart_ptr<non_const_base,CLONE_POLICY>&theOtherSmart_ptr):theWrappedPointer(theOtherSmart_ptr.theWrappedPoin ter){}smart_ptr(const smart_ptr<const non_const_base,CLONE_POLICY>&theOtherSmart_ptr):theWrappedPointer(theOtherSmart_ptr.theWrappedPoin ter){}template<class T>smart_ptr(const smart_ptr<T,CLONE_POLICY>& theOtherSmart_ptr,typename boost::enable_if<boost::is_base_of<non_const_base, typenameboost::remove_const<T>::type>,T>::type *pp=0):theWrappedPointer(theOtherSmart_ptr.theWrappedPoin ter){}smart_ptr(){}BaseClass *operator->()const{returntheWrappedPointer.raw_pointer;}virtual ~smart_ptr(){}private:smart_ptr & operator=(const BaseClass *ptr);CLONE_POLICY<non_const_basetheWrappedPointer;};#endif--------------------------------------------------------------------------------------------------------------<main.cpp>#include<vector>#include<iostream>#include<cctype>#include"smart_ptr.h"using namespace std;class Base {public:Base():ch(''*''){Count++;}Base(const Base&):ch(''*''){Count++;}virtual char show(){return ch;}virtual ~Base(){Count--;}virtual void v()const=0;static unsigned long Count;private:char ch;};unsigned long Base::Count(0);/// this will give us lots of derived classestemplate<char ch_>class Derived :public Base {public:Derived():ch(ch_){Count++;}Derived(const Derived<ch_>&):ch(ch_){Count++;}virtual char show(){return ch;}virtual ~Derived(){Count--;}virtual void v()const{}static unsigned long Count;private:char ch;};template<char ch_>unsigned long Derived<ch_>::Count(0);template<char ch_>class DerivedSquared :public Derived<ch_{public:DerivedSquared():ch(std::tolower(ch_)){Count++;}DerivedSquared(const DerivedSquared<ch_>&):ch(std::tolower(ch_)){Count++;}virtual char show(){return ch;}virtual ~DerivedSquared(){Count--;}virtual void v()const{}static unsigned long Count;private:char ch;};template<char ch_>unsigned long DerivedSquared<ch_>::Count(0);int main() {smart_ptr<Derived<''B''>,BuxWrappedPointertheDPA(newDerivedSquared<''B''>);cout << theDPA->show();smart_ptr<Base,BuxWrappedPointertheDPA2(theDPA);cout << theDPA2->show();}-------------------------------------------------------------------------------------------------------------------------NSC 解决方案Why do you need such a beast ? i.e. what are the requirements and use case ?It''s kind of hard to read. http://groups.google.co.uk/group/com...e5c18bc6bb5c7eWhat a coincidence, your post prompted me to rethink that, too. I appearsthat we arrived at very similar conclusions (see below).General comment: you lines are too long.*>BaseClassOh boy, you are quite boost-savvy! I do not quite see, however, what allthis enable_if< ... stuff is doing for you. If it is just to get theright compiler errors if you docopy_ptr< Base b_ptr = copy_ptr< NotDerived >( new not Derived() );then, I think, there are simpler means of going about it (see below). But Imight be missing something here.class smart_ptr {public:****************typedef typename boost::remove_const<BaseClass>::type****************non_const_base;****************template<class T,template <classclass CLONE_POLICY >****************friend class smart_ptr;g++ gives me an error for the above saying that the declaration ofCLONE_POLICY shadows the template parameter.Why is this destructor virtual?Again, I find the boost stuff confusing. What design specs necessitate theuse of non_const_base and remove_const?I found thatsmart_ptr<inti_ptr ( new int ( 5 ) );cout << *i_ptr << ''\n'';gives me an error. You should add operator*.I worked a little on the non-policy based version to have copy_ptr<Baseandcopy_ptr<Derivedbehave as desired. I also added a compile time checkagains using non-polymorphic base classes. This might be overkill.(Alternatively, one could think about adding a deleter-function that woulduse the right destructor in any case.)#include <algorithm// std::swaptemplate < typename T >struct non_polymorphic_class_error {enum {trigger = sizeof( dynamic_cast<void*>( static_cast<T*>(0) ) )};};// The clone function:// ===================template < typename T >void * clone ( void * ptr ) {return ( ptr == 0 ? 0: static_cast<void*>( new T ( *( static_cast<T*>( ptr ) ) ) ) );}// The copy_ptr:// =============template < typename T >class copy_ptr {friend void swap ( copy_ptr<T& p, copy_ptr<T& q ) {std::swap( p.raw_ptr, q.raw_ptr );std::swap( p.clone_fct, q.clone_fct );}template < typename D >friend class copy_ptr;/*The idea is that in addition to a pointer, we also needa pointer to the _appropriate_ clone function.*/T * raw_ptr;void * ( *clone_fct ) ( void * );public:copy_ptr ( T * ptr = 0): raw_ptr ( ptr ), clone_fct ( clone<T){}template < typename D >copy_ptr ( D * ptr ): raw_ptr ( ptr ), clone_fct ( clone<D){non_polymorphic_class_error<Td2;}// copy construction clones:copy_ptr ( copy_ptr const & other ): raw_ptr ( static_cast<T*>( other.clone_fct( other.raw_ptr ) ) ), clone_fct ( other.clone_fct ){}template < typename D >copy_ptr ( copy_ptr<Dconst & other ): raw_ptr ( static_cast<D*>( other.clone_fct( other.raw_ptr ) ) ), clone_fct ( other.clone_fct ){non_polymorphic_class_error<Td2;}// destruction frees the pointee~copy_ptr ( void ) {delete ( raw_ptr );}// assignment reduces to copy construction// (for correctness and exception safety):copy_ptr & operator= ( copy_ptr const & other ) {copy_ptr dummy ( other );swap( *this, dummy );return( *this );}template < typename D >copy_ptr & operator= ( copy_ptr<Dconst & other ) {copy_ptr dummy ( other );swap( *this, dummy );return( *this );}T const * operator-( void ) const {return( raw_ptr );}T * operator-( void ) {return( raw_ptr );}T const & operator* ( void ) const {return( *( this->operator->() ) );}T & operator* ( void ) {return( *( this->operator->() ) );}}; // copy_ptr<T>Please, let me know what you think.BestKai-Uwe Bux http://groups.google.co.uk/group/com...e5c18bc6bb5c7eWhat a coincidence, your post prompted me to rethink that, too. I appearsthat we arrived at very similar conclusions (see below).General comment: you lines are too long.I apologise for the length of the lines, I think my problem is 2-fold.Firstly I am not a proffesional developerI have never really learnt a good style for code presentation, but Isuppose tools like doxygen make that anon-excuse. Secondly, I think something just went wrong with thepasting.*>BaseClassOh boy, you are quite boost-savvy! I do not quite see, however, what allthis enable_if< ... stuff is doing for you. If it is just to get theright compiler errors if you do copy_ptr< Base b_ptr = copy_ptr< NotDerived >( new not Derived() );then, I think, there are simpler means of going about it (see below). But Imight be missing something here.re enable_if from the boost websiteThe enable_if family of templates is a set of toolsto allow a function template or a classtemplate specialization to include or exclude itselffrom a set of matching functions orspecializations based on properties of its templatearguments. For example, one can definefunction templates that are only enabled for, andthus only match, an arbitrary set of typesdefined by a traits class. The enable_if templatescan also be applied to enable class templatespecializations.So I am only enablingBuxWrappedPointer(const BuxWrappedPointer<MiddleBase>&theMiddleBase)when MiddleBase is derived FROM Base. This allows :clone_ptr<MiddleBasetheMiddleClass_ptr(new Derived);clone_ptr<BasetheBaseClass_ptr (theMiddleClass_ptr); //casting up the hierachy should be allowedbut disallows everything else includingclone_ptr<BasetheBaseClass_ptr (new Derived);clone_ptr<MiddleBasetheMiddleBaseClass_ptr(theMiddleClass_ptr); // casting down the hierachy should NOT beallowed class smart_ptr { public: typedef typename boost::remove_const<BaseClass>::type non_const_base; template<class T,template <classclass CLONE_POLICY > friend class smart_ptr;g++ gives me an error for the above saying that the declaration ofCLONE_POLICY shadows the template parameter.Why is this destructor virtual?Again, I find the boost stuff confusing. What design specs necessitate theuse of non_const_base and remove_const?This non_const_base gives me ''type'' from ''const type''So this allows me to do :copy_ptr<BasethePtr(new Derived);copy_ptr<const BasetheConstPtr(thePtr);Of course this may not be so important for deep copy but may be usefulfor other policies. But I still want the Policyclass to be template on Base, even if the smart_ptr is templated onBase or const Base, in some sense they are the same.The linetemplate<class T>smart_ptr(const smart_ptr<T,CLONE_POLICY>&should be something liketemplate<class T, template <classclass OTHER_CLONE_POLICY>smart_ptr(constsmart_ptr<T,OTHER_CLONE_POLICY>&sorry, I use both Linux gcc and msvc, and I happend to be using msvc atthat moment, and it did not complain.Again I am using the boost template stuff ONLY when T is derived FROMBase, for same reasons as above. But I m ripping of the const of thembefore I compare. That isBaseClass = Base T = MiddleBaseThis is okBaseClass = const Base T = MiddleBaseThis is okBaseClass = Base T = const MiddleBaseThis is okBaseClass = const Base T = constMiddleBase This is okI found that smart_ptr<inti_ptr ( new int ( 5 ) ); cout << *i_ptr << ''\n'';gives me an error. You should add operator*.I completely agree, I should have posted a more complete class. But Ijust wanted to show my extension to your trickleaving out the other details. I intend to add other members too, suchas interoperability with auto_ptr etcI forbid myslef from using dynamic_cast, but I would have to try toremeber the reasons why. But I do have a question.Isn''t it true that dynamic_cast happens at runtime and therefore wehave a overhead, whereas static_cast takes place at compile time, sowe don''t. I think the boost is_base combined with boost enable_if letsus ''error check'' at compile time.I by no means am ''boost savy'' I didn''t even know about is_basr until afew days ago. Its just that I find some real magical bits offunctionality there, its a waste of time trying to re-code some of it,especially when the boost coders are in a far superior league toof programmers to me. Also I prefer to do as much as possible atcompile time than at runtime.NPS I think my first ever use of is_base was to write this class. 这篇关于Deep Copy智能指针不需要虚拟副本构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-18 13:35