Template class imitating an ordinary variable

Jan 10, 2013 at 7:30am
Hi there,

I have to write a template class which will be imitating an ordinary variable such as int. It has to be based on dynamic allocation. Following is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
 { Wrapper < double> el1, el2;

el1=3.8;//el1=new double, *el1 = 3.8, counter=1
el2=el1;//counter=2

if(1){
Wrapper< double> el3;

el3=el2;//counter=3
                              
} //counter=2, free el3

} // counter=0, free el1, el2 


It should include handy and useful overloaded operators and functions. Besides, I have to implement proper exception handling (according to my prerequisites, the following throws are incorrect: throw 7 or throw "Error in module foo).

So here are my questions:

1) What is proper exception handling? I should derive my own exception class from the standard one named exception?

2) Where are potentially dangerous places in such class to throw an exception?

3) What useful overloaded operators along with operator+ or operator- should I embed into my class?

Regards.
Last edited on Jan 10, 2013 at 7:48am
Jan 10, 2013 at 8:02am
> What is proper exception handling? I should derive my own exception class from the standard one named

Not necessarily. You could throw std::overflow_error or std::invalid_argument.
And ideally catch them by reference to const.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
try
{
    // ...
}  

catch( const std::overflow_error& o ) 
{
    // handle overflow
}

catch( const std::exception& e )
{
    // handle other errors
}


> Where are potentially dangerous places in such class to throw an exception?

In the normal case, in destructors, move constructors or move assignment operators.

However, if you hold raw resources, everywhere.


> What useful overloaded operators along with operator+ or operator- should I embed into my class?

Other than conversion operators, only those operators where you want to intercept and check for errors (overflow etc) are required. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <memory>
#include <stdexcept>

template< typename T > struct wrapper
{
    wrapper( const T& v = T() ) : p( new T(v) ) {}
    explicit wrapper( T*&& pp ) : p(pp) { if(!p) throw std::invalid_argument( "nullptr!" ) ; }
    // ...

    operator T& () { if(!p) throw std::domain_error( "dereference of nullptr!" ) ; return *p ; }
    operator const T& () const { if(!p) throw std::domain_error( "dereference of nullptr!" ) ; return *p ; }
    // ...

    std::unique_ptr<T> p ;
};

int main()
{
    wrapper<double> d1(23.4), d2( new double(5.8) ) ;
    std::cout << d1 * d2 << '\n' ;
}
Last edited on Jan 10, 2013 at 8:04am
Topic archived. No new replies allowed.