N
Nindi73
A few days a ago I posted my code for a deep copy pointer which
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.
http://groups.google.co.uk/group/co...9af25/89e5c18bc6bb5c7e?hl=en#89e5c18bc6bb5c7e
However there was one possible extension to that code :
'The trade-off is that copy_ptr<Base> and copy_ptr<Derived> are
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here 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/comp.lang.c++/browse_thread/thread/b...
template<class DerivedClass>
void * Buxclone(const void *theOtherPtr){
return new DerivedClass(*static_cast<const
DerivedClass*>(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,
typename
boost::enable_if<boost::is_base_of<BaseClass,MiddleBase>,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<BaseClass> temp(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<const
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"
template<
class BaseClass,
class smart_ptr {
public:
typedef typename boost::remove_const<BaseClass>::type non_const_base;
template<class T,template <class> class CLONE_POLICY >
friend class smart_ptr;
template<class DerivedClass>
smart_ptr(DerivedClass *
theDerivedPointer_):theWrappedPointer(theDerivedPointer_){}
smart_ptr(const smart_ptr<non_const_base,CLONE_POLICY>&
theOtherSmart_ptr):
theWrappedPointer(theOtherSmart_ptr.theWrappedPointer){}
smart_ptr(const smart_ptr<const non_const_base,CLONE_POLICY>&
theOtherSmart_ptr):
theWrappedPointer(theOtherSmart_ptr.theWrappedPointer){}
template<class T>
smart_ptr(const smart_ptr<T,CLONE_POLICY>& theOtherSmart_ptr,
typename boost::enable_if<boost::is_base_of<non_const_base,typename
boost::remove_const<T>::type>,T>::type *pp=0):
theWrappedPointer(theOtherSmart_ptr.theWrappedPointer){}
smart_ptr(){}
BaseClass *operator->()const{return
theWrappedPointer.raw_pointer;}
virtual ~smart_ptr(){}
private:
smart_ptr & operator=(const BaseClass *ptr);
CLONE_POLICY<non_const_base> theWrappedPointer;
};
#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 classes
template<char ch_>
class Derived ublic 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 ublic 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'>,BuxWrappedPointer> theDPA(new
DerivedSquared<'B'>);
cout << theDPA->show();
smart_ptr<Base,BuxWrappedPointer> theDPA2(theDPA);
cout << theDPA2->show();
}
doesn't require the pointee object to have a virtual copy constructor.
I need help with checking that it was exception safe and exception
neutral/
I got a reply from Bux with his code for a smart pointer with far fewer
lines of code
and more cleaner design, not over engineered like mine.
http://groups.google.co.uk/group/co...9af25/89e5c18bc6bb5c7e?hl=en#89e5c18bc6bb5c7e
However there was one possible extension to that code :
'The trade-off is that copy_ptr<Base> and copy_ptr<Derived> are
unrelated '
Kai-Uwe Bux
I think I have managed to implement this extension, so I post my code
here 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/comp.lang.c++/browse_thread/thread/b...
template<class DerivedClass>
void * Buxclone(const void *theOtherPtr){
return new DerivedClass(*static_cast<const
DerivedClass*>(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,
typename
boost::enable_if<boost::is_base_of<BaseClass,MiddleBase>,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<BaseClass> temp(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<const
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"
template<
class BaseClass,
class smart_ptr {
public:
typedef typename boost::remove_const<BaseClass>::type non_const_base;
template<class T,template <class> class CLONE_POLICY >
friend class smart_ptr;
template<class DerivedClass>
smart_ptr(DerivedClass *
theDerivedPointer_):theWrappedPointer(theDerivedPointer_){}
smart_ptr(const smart_ptr<non_const_base,CLONE_POLICY>&
theOtherSmart_ptr):
theWrappedPointer(theOtherSmart_ptr.theWrappedPointer){}
smart_ptr(const smart_ptr<const non_const_base,CLONE_POLICY>&
theOtherSmart_ptr):
theWrappedPointer(theOtherSmart_ptr.theWrappedPointer){}
template<class T>
smart_ptr(const smart_ptr<T,CLONE_POLICY>& theOtherSmart_ptr,
typename boost::enable_if<boost::is_base_of<non_const_base,typename
boost::remove_const<T>::type>,T>::type *pp=0):
theWrappedPointer(theOtherSmart_ptr.theWrappedPointer){}
smart_ptr(){}
BaseClass *operator->()const{return
theWrappedPointer.raw_pointer;}
virtual ~smart_ptr(){}
private:
smart_ptr & operator=(const BaseClass *ptr);
CLONE_POLICY<non_const_base> theWrappedPointer;
};
#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 classes
template<char ch_>
class Derived ublic 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 ublic 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'>,BuxWrappedPointer> theDPA(new
DerivedSquared<'B'>);
cout << theDPA->show();
smart_ptr<Base,BuxWrappedPointer> theDPA2(theDPA);
cout << theDPA2->show();
}