Reputation: 12351
Maybe I'm overcomplicating things, but then again, I do sort of like clean interfaces. Let's say I want a specialization of auto_ptr for an fstream - I want a default fstream for the generic case, but allow a replacement pointer?
template <>
class auto_ptr<fstream> {
static fstream myfStream;
fstream* ptr;
public:
auto_ptr() {
// set ptr to &myfStream;
}
reset(fstream* newPtr) {
// free old ptr if not the static one.
ptr = newPtr
};
}
Would you consider something different or more elegant? And how would you keep something like the above from propagating outside this particular compilation unit?
[The actual template is a boost::scoped_ptr.]
EDIT:
It's a contrived example. Ignore the fstream - it's about providing a default instance of object for an auto_ptr. I may not want to provide a specialized instance, but would like to keep the auto_ptr semantics for this static default object.
class UserClass {
public:
auto_ptr<fstream> ptr;
UserClass() { }
}
I may not provide an dynamic object at construction time - I still want it to have a meaningful default. Since I'm not looking at ownership-transfer semantics, it really shouldn't matter that my pointer class is pointing to a statically allocated object, no?
Upvotes: 3
Views: 483
Reputation: 137850
You might get something that compiles and works, but I wouldn't do that if I were you.
Boost defines certain functionality for the construction of an auto_ptr
. If you redefine that somehow, you have violated their specification.
Invent a name for your new functionality, make it a factory function, and don't worry about specializing someone else's template.
EDIT: deriving from auto_ptr
is another option, if you're really set on changing initialization semantics:
tempate < class T, T *d >
struct defaulted_auto_ptr
: public auto_ptr< T > {
defaulted_auto_ptr( T *p = d ) throw() : auto_ptr<T>( p ) {} // set default
defaulted_auto_ptr( auto_ptr<T> &r ) throw()
: auto_ptr<T>( r ) {} // allow conversion
template< class O > defaulted_auto_ptr( auto_ptr<O> &r ) throw()
: auto_ptr<T>( r ) {}
};
fstream default_file;
typedef defaulted_auto_ptr< fstream, &default_file > file_ptr;
auto_ptr< fstream > baseptr = file_ptr(); // can assign to auto_ptr, but unsafe
I'm a little doubtful of the cost-benefit tradeoff of this, but it's better than entirely reimplementing auto_ptr
.
You still have to figure out what to do if a defaulted object is destroyed. default_file
above will be delete
d, potentially many times.
Upvotes: 1
Reputation:
This wouldn't end up good. The biggest problem is that std::auto_ptr deletes the underlying object in its destructor. This means your default parameter can't be static. The only choice you can make is to do a lot of hacks there and IMHO the price you'll pay while maintaining all that crappy code isn't worth the small advantage you'd have.
Upvotes: 2
Reputation: 25533
That looks reasonable to me, could be confusing if it's use is widespread in a codebase and not documented though.
I notice you are being carful, but I'm going to stress it anyway: make sure you don't double-free your static object!
Upvotes: 1