[Gdal-dev] GDAL CPLError and C++ Exceptions
Ray Gardener
rayg at daylongraphics.com
Wed Nov 29 17:24:34 EST 2006
Yes, you're absolutely right; my bad, sorry about that. That's what I
get for hastily coding examples after midnight. :) The ownership policy
on original objects needs to be defined better.
Ray
Mateusz Loskot wrote:
> Ray Gardener wrote:
>> fwiw, for those preferring exception-based error reporting all around:
>>
>> Since GDAL implements return code based error reporting, if you don't
>> mind wrapping the GDAL APIs, you can create an exceptions-based
>> interface, e.g. if using the GDAL C++ API:
>>
>> class GDALDataset_plus
>> {
>> public:
>> // After normally instancing a dataset, instance a myDataset
>> // and assign the original dataset to this member var
>> // (or if instancing locally, use the second ctor).
>> GDALDataset* m_pDataset;
>>
>> GDALDataset_plus() : m_pDataset(NULL) {}
>> GDALDataset_plus(GDALDataset* p) : m_pDataset(p) {}
>> virtual ~GDALDataset_plus() { if(m_pDataset) delete m_pDataset; }
>>
>> void AddBand(type, options)
>> {
>> assert_ptr(m_pDataset);
>> if(CE_None != m_pDataset->AddBand(type, options))
>> throw gdal_exception();
>> }
>>
>> // ... wrappers around remaining GDALDataset methods
>> };
>>
>> // ... GDALxxx_plus class versions of remaining GDAL classes
>>
>>
>> And then you can do stuff like:
>>
>> GDALDataset dataset_org;
>> GDALDataset_plus dataset(&dataset_org);
>
> Ray,
>
> This code of usage is ill-formed.
> dataset_org is an object with automatic storage duration.
> Now, pointer to dataset_org is passed to constructor of
> GDALDataset_plus, with implicit *ownership transfer*.
> So, it results in m_pDataset pointing to automatic object.
>
> Next, 1) destructor of GDALDataset_plus calls delete on pointer to
> automatic object (dataset_org),
> 2) dataset_org will be destroyed automatically on the scope exit (EOF
> object lifetime).
>
> You must not call delete on automatic storage duration objects.
>
>> try
>> {
>> dataset.AddBand(type, options);
>> // other stuff, with no checking of return codes
>> // since the _plus classes return 'void'
>> }
>> catch(gdal_exception& e) { msg("GDAL exception occurred"); }
>> catch(...) { msg("Unknown error"); }
>
> OK, but the GDALDataset is allocated dynamically and returned by pointer
> from GDAL and it needs to be closed and destroyed explicitly by the wrapper.
> In the example above, 'dataset' of type of GDALDataset is presented
> as local object what's very rare or even impossible situation when using
> GDAL.
>
>> The wrappers also enable other niceties, like avoiding having to include
>> error variables as arguments (if you always prefer such cases to just
>> throw an exception instead), and having the return type of a function
>> always be non-error-related. e.g.,
>> int foo(void) instead of errcode foo(int* p)
>
> It's also possible to use smart pointers like shared_ptr with custom
> deleter, as a simple wrapper:
>
> boost::shared_ptr<OGRFeature> feature(layer->GetFeature(0),
> OGRFeature::DestroyFeature);
>
> Feature object returned by GetFeature will be destroyed properly
> by DestroyFeature call.
>
> Cheers
More information about the Gdal-dev
mailing list