Similar Threads:
1.Exception Safe Code - RAII
2.Exception safe & Exception Neutral deep_copy smart pointer
Hi,
I am in need of a deep copy smart pointer (Boost doesn't provide one)
which doesnt require the contained types to have a virtual copy
constructor. I wrote a smart pointer class that I think meets these
requirements, but after reading the chapter on exceptions in
'Exceptional C++':Sutter, I am not sure if its is really Exception safe
or Exception Neutral. I suppose putting the theory in that chapter into
practice isn't trivial.
--------------------------------------------------------------------------------------------
<Inner_deepcpy_ptr.h>
#ifndef DEEP_COPY_IMPL_HEADER_GUARD
#define DEEP_COPY_IMPL_HEADER_GUARD
#include<boost/pool/singleton_pool.hpp>
#include<boost/utility.hpp>
template<class BaseClass>
class Inner_deepcpy_ptrAbstract : boost::noncopyable {
public:
virtual BaseClass * GetBasePointer()=0;
virtual Inner_deepcpy_ptrAbstract<BaseClass> *clone()=0;
virtual ~Inner_deepcpy_ptrAbstract(){};
static void Delete( Inner_deepcpy_ptrAbstract<BaseClass> *);
protected:
typedef void (*FreeFunc)(void *const);
FreeFunc eraser;
};
template<class BaseClass,class DerivedClass>
class Inner_deepcpy_ptr :public Inner_deepcpy_ptrAbstract<BaseClass>{
public:
Inner_deepcpy_ptr(DerivedClass*
theDerivedPointer_):theDerivedPointer(theDerivedPointer_){};
DerivedClass * GetBasePointer(){return theDerivedPointer;}
virtual Inner_deepcpy_ptr<BaseClass,DerivedClass> *clone()
{
return New(new DerivedClass(*theDerivedPointer) );
}
static Inner_deepcpy_ptr<BaseClass,DerivedClass> * New(DerivedClass*
theDerivedPointer_);
virtual ~Inner_deepcpy_ptr(){delete theDerivedPointer;}
private:
DerivedClass *theDerivedPointer;
static void * operator new(std::size_t); //DO NOT IMPLEMENT THIS ,
DON'T WANT IT USED BY ACCIDENT
static void * operator new(std::size_t,void *ptr){return ptr;}
static void operator delete(void *){};
};
template<class BaseClass,class DerivedClass>
struct Pool {
typedef
boost::singleton_pool<int,sizeof(Inner_deepcpy_ptr<BaseClass,DerivedClass>)>
type;
};
template<class BaseClass,class DerivedClass>
Inner_deepcpy_ptr<BaseClass,DerivedClass> *
Inner_deepcpy_ptr<BaseClass,DerivedClass>::New( DerivedClass*
theDerivedPointer_)
{
Inner_deepcpy_ptr<BaseClass,DerivedClass> * thePtr =
static_cast<Inner_deepcpy_ptr<BaseClass,DerivedClass>
*>(Pool<BaseClass,DerivedClass>::type::malloc());
new
(thePtr)Inner_deepcpy_ptr<BaseClass,DerivedClass>(theDerivedPointer_);
thePtr->eraser = &Pool<BaseClass,DerivedClass>::type::free;
return thePtr;
}
template<class BaseClass>
void
Inner_deepcpy_ptrAbstract<BaseClass>::Delete(Inner_deepcpy_ptrAbstract<BaseClass>
*ptr)
{
if(ptr) {
ptr->~Inner_deepcpy_ptrAbstract<BaseClass>();
FreeFunc eraser = ptr->eraser;
eraser(ptr);
}
}
#endif
--------------------------------------------------------------------------------------------
<deepcpy_ptr.h>
#ifndef DEEP_COPY_HEADER
#define DEEP_COPY_HEADER
#include"Inner_deepcpy_ptr.h"
template<class BaseClass>
class deepcpy_ptr {
public:
template<class DerivedClass>
deepcpy_ptr(DerivedClass * theDerivedPointer_):
theWrappedPointer(Inner_deepcpy_ptr<BaseClass,DerivedClass>::New(theDerivedPointer_)){}
deepcpy_ptr():theWrappedPointer(0){}
deepcpy_ptr(const deepcpy_ptr<BaseClass>& theOtherdeepcpy_ptr);
deepcpy_ptr & operator=(const deepcpy_ptr<BaseClass>&
theOtherdeepcpy_ptr);
BaseClass *operator->();
const BaseClass *operator->()const;
virtual
~deepcpy_ptr(){Inner_deepcpy_ptrAbstract<BaseClass>::Delete(theWrappedPointer);}
private:
deepcpy_ptr & operator=(const BaseClass *ptr);
Inner_deepcpy_ptrAbstract<BaseClass> *theWrappedPointer;
};
template<class BaseClass>
deepcpy_ptr<BaseClass>::deepcpy_ptr(const deepcpy_ptr<BaseClass>&
theOtherdeepcpy_ptr){
if(theOtherdeepcpy_ptr.theWrappedPointer)
// don't need to set theWrappedPointer to 0, if the following throws,
don't get an
// object anyway
theWrappedPointer =(theOtherdeepcpy_ptr.theWrappedPointer)->clone();
else theWrappedPointer=0;
}
template<class BaseClass>
BaseClass *deepcpy_ptr<BaseClass>::operator->(){
if(theWrappedPointer)return theWrappedPointer->GetBasePointer();
return 0;
}
template<class BaseClass>
const BaseClass *deepcpy_ptr<BaseClass>::operator->()const {
if(theWrappedPointer)return theWrappedPointer->GetBasePointer();
return 0;
}
template<class BaseClass>
deepcpy_ptr<BaseClass> & deepcpy_ptr<BaseClass>::operator=(const
deepcpy_ptr<BaseClass>& theOtherdeepcpy_ptr){
Inner_deepcpy_ptrAbstract<BaseClass> *temp =
(theOtherdeepcpy_ptr.theWrappedPointer)->clone();
if(temp) {
// we have the temp object to get a bit of exception saftey
Inner_deepcpy_ptrAbstract<BaseClass>::Delete(theWrappedPointer);
theWrappedPointer = temp;
}
return *this;
}
#endif
---------------------------------------------------------------------------------------------------------
<main.cpp>
#include<iostream>
#include"deepcpy_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()=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 :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(){}
static unsigned long Count;
private:
char ch;
};
template<char ch_>
unsigned long Derived<ch_>::Count(0);
int main() {
cout << "There are " << Derived<'A'>::Count << "As" <<'\n';
{
deepcpy_ptr<Base> theDPA(new Derived<'A'>);
deepcpy_ptr<Base> theDPA2(theDPA);
cout << "There are " << Derived<'B'>::Count << "Bs" <<'\n';
try {
deepcpy_ptr<Base> theDPB(new Derived<'B'>);
deepcpy_ptr<Base> theDPB2;
theDPB2 = theDPB;
cout << "There are " << Derived<'B'>::Count << "Bs" <<'\n';
deepcpy_ptr<Base> theDPB3(new Derived<'B'>);
deepcpy_ptr<Base> theDPB4(theDPB3);
deepcpy_ptr<Base> theDPB5(theDPB4);
}
catch(int i) {
}
cout << "There are " << Derived<'B'>::Count << "Bs" <<'\n';
deepcpy_ptr<Base> theDPA3;
theDPA3 = theDPA;
}
cout << "There are " << Derived<'A'>::Count << "As";
}
3.safe for exception code?
in the book EC++ chapter 11, with this code
( pb is a member of class )
WIdget& WIdget::operator=(const WIdget& rhs)
{
Bitmap *pOrig = pb;
pb = new Bitmap(*rhs.pb);
delete pOrig;
return *this;
}
book says this code is safe for exception, but what if exception
occurs in " pb = new Bitmap(*rhs.pb);" this line?
and it's going to run the next line(delete pOrig;). this will result
this object lose its bitmap pointer.
this is right? or wrong?
4.Is this code exception safe?
5.Is this exception-safe code template correct?
6. Sample program: Try / Catch exceptions user defined exceptions derived from System.Exception
7. Publish exception to Email in Exception Handling Exception Block
8. exception specifications legal in C++/CLI