Exception Specification [was: Exception Safe Code - RAII]

c++ moderated

Re: Exception Specification [was: Exception Safe Code - RAII]

Postby Frank Birbacher » Sat, 28 Mar 2009 11:04:54 GMT

Hi!

Arne Mertz schrieb:

Well, yes.


Well, not for each case. If my dtors actually contain no code that could
throw and all members have a no throw dtor themselves, there is not need
to generate code to check the exception specification.

Just make sure, each class defined its dtor that way. But I'll report if
I run into performance problems because my dtors take to long figuring
out whether they may throw or not.


Being pedantic I add "throw()" to dtors so the program will abort if an
exception is raised where it shall not. I take this like an assert.
Despite the overhead. I'll try it on a private project of mine.

Frank

-- 
      [ See  http://www.**--****.com/ ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]


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



Return to c++ moderated

 

Who is online

Users browsing this forum: No registered users and 20 guest