template specialization of a auto_ptr<T> - c++

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?

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.

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!

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 deleted, potentially many times.

Related

Is it sensible to use shared_ptr instead of unique_ptr as class member just to avoid implicit copy constructor deletion?

I would like to preserve the default copy-constructor of a large-ish (but say not particularly complex*) class, but ideally would like to replace some raw pointer member with a smart-pointer alternative.
unique_ptr seems to be the default for this, but it implicitly deletes the copy constructor for my class.
shared_ptr instead would allow me to preserve the class' copy constructor. Could that likely be a good reason to simply stick to shared_ptr, even if I do not genuinely want to 'share' the resource; I really only want to preserve the readily available copy constructor (annoying to write a manual copy constructor for the entire class, just to replace a pointer with a unique_ptr), just as I had it when I still used raw pointer.
Searching for when to use shared_ptr vs. unique_ptr, I never see the simple preservation of the copy-constructor indicated as a possible key reason to use shared_ptr (possible exception https://stackoverflow.com/a/16030118/3673329 but not giving any detail), but I also do not directly see any reason why this could not be a valid choice.
I reckon shared_ptr may be a bit more resource intensive, but assume my case where this is no real problem.
*In particular, the default/shallow copying of the class was fine for my purposes as long as I used raw pointer members instead of smart ones.
If the only reason to use std::shared_ptr is to retain default copy constructibility of your class, you prioritize ease of use over the intended semantics of your class with respect to resource handling. In my opinion, you have to decide up front whether the class shall share its resources or exclusively own it. If you are unsure whether the class should share its resources with copied instances or not, something else in the design might at least be suspicious.
There might be an exception to this guideline, and that is std::shared_ptr<const YourType>. In the case of read only access, it might be acceptable to use such a technique to allow for default copy construction (although in a different context, here is where Sean Parent says that std::shared_ptr<const T> is acceptable to obtain value semantics).
Note one further implication: if you share a std::shared_ptr instance, you are not only sharing state and functionality of the pointee, you also share lifetime control. If the latter is not what you intend, just share a reference (preferable) or a raw pointer to the pointee, with access e.g. via a getter-like member function. If the consuming parts of your class can't know whether the pointee is still alive or has already been destroyed, a std::weak_ptr could be an option.
There is still a great deal of advantage in using a unique_ptr and providing the missing copy operations manually.
You get the correctness guarantees plus an easy customisation point for inner object cloning.
example:
#include <memory>
struct LargeImplObject
{
int x[1000];
};
struct CopyableHandle
{
using impl_class = LargeImplObject;
using implementation_type = std::unique_ptr<impl_class>;
CopyableHandle()
: impl_(construct())
{}
CopyableHandle(CopyableHandle&&) noexcept = default;
CopyableHandle& operator=(CopyableHandle&&) noexcept = default;
CopyableHandle(CopyableHandle const& other)
: impl_(other.clone())
{}
CopyableHandle& operator=(CopyableHandle const& other)
{
impl_ = other.clone();
return *this;
}
// note: no destructor
private:
// customisation points
static auto construct() -> implementation_type
{
return std::make_unique<impl_class>();
}
auto clone() const -> implementation_type
{
return std::make_unique<impl_class>(*impl_);
}
implementation_type impl_;
};
int main()
{
auto a = CopyableHandle();
auto b = a;
auto c = std::move(a);
a = std::move(c);
}

Enforce no bald pointers in C++

Generally speaking, in this crazy modern world full of smart pointers, I'm coming round to the fact that bald/bare pointers shouldn't be in method signatures.
I suppose there might be some cases where you need bald pointers for performance reasons but certainly I've always managed with references or references to smart pointers.
My question is this, can anyone suggest an automated way to enforce this? I can't see a way with clang, GCC or vera++
I think it is ok for non-owning raw-pointers to be used in method signatures. It is not ok to use "owning" raw-pointers.
For example this is quite ok:
void bar(const Widget* widget) {
if (widget)
widget->doSomething();
}
void foo() {
Widget w;
bar(&w);
}
If you want the Widget to be nullable you can't use a reference and using a smart pointer would be slower and not express the ownership model. The Widget can be guaranteed to be alive for the whole scope of foo. bar simply wants to "observe" it so a smart pointer is not needed. Another example where a non-owning raw-pointer is appropriate is something like:
class Node {
private:
std::vector<std::unique_ptr<Node>> children_; // Unique ownership of children
Node* parent_;
public:
// ...
};
The Node "owns" its children and when a Node dies its children die with it. Providing encapsulation of Node hasn't been broken, a Node can guarantee its parent is alive (if it has one). So a non-owning raw-pointer is appropriate for a back reference to the parent. Using smart pointers where they are not required makes code harder to reason about, can result in memory leaks and is premature pessimization.
If smart pointers are used throughout instead, all kinds of things can go wrong:
// Bad!
class Node {
private:
std::vector<std::shared_ptr<Node>> children_; // Can't have unique ownership anymore
std::shared_ptr<Node> parent_; // Cyclic reference!
public:
// Allow someone to take ownership of a child from its parent.
std::shared_ptr<Node> getChild(size_t i) { return children_.at(i); }
// ...
};
Some of these problems can be solved by using weak_ptr instead of shared_ptr but they still need to be used with care. A weak_ptr is a pointer that has the option of owning.
The point is to use the appropriate kind of pointer in the appropriate context and to have an ownership model that is as simple as possible.
And no, I don't think there is an automated way of enforcing this, it is part of the design. There are tricks you can use like Cheersandhth.-Alf said to try and enforce a particular class is used in the way you want by restricting access.
I don't know of any automated tool to do this, but such a check wouldn't be too hard to implement in cppcheck, which is open source and AIUI offers an easy way to add new rules.
I don't think it's a good idea to completely stay away from raw (bald, bare) pointers even for function arguments. But it can sometimes be a good idea to make sure that all instances of a certain type are dynamic and owned by smart pointers. This involves two measures:
Ensure (to the degree practical) that the type can only be instantiated dynamically.
Ensure (to the degree practical) that instantiation yields a smart pointer.
The first point is easy: just make the destructor non-public, and voilá, the few remaining ways to instantiate that type non-dynamically are not very natural. Any simple attempt to declare a local or namespace scope variable will fail. As will simple attempts to use that type directly as a data member type:
#include <memory>
template< class Type >
void destroy( Type* p ) { delete p; }
class Dynamic
{
template< class Type > friend void destroy( Type* );
protected:
virtual ~Dynamic() {}
};
//Dynamic x; //! Nope.
struct Blah
{
Dynamic x; //! Nope, sort of.
};
auto main()
-> int
{
//Dynamic x; //! Nope.
new Blah; //!Can't delete, but new is OK with MSVC 12...
}
Visual C++ 12.0 unfortunately accepts the above code as long as the out-commented statements remain out-commented. But it does issue a stern warning about its inability to generate a destructor.
So, Dynamic can only be created dynamically (without using low-level shenanigans, or ignoring that MSVC warning and accepting a memory leak), but how to ensure that every new instance is owned by a smart pointer?
Well you can restrict access to the constructors so that a factory function must be used. Another way to ensure use of the factory function is to define a placement allocation function, operator new, that an ordinary new-expression can't access. Since that's most esoteric and possibly non-trivial, and not of clear-cut value, the below code just restricts access to the constructors:
#include <memory> // std::shared_ptr
#include <utility> // std::forward
// A common "static" lifetime manager class that's easy to be-"friend".
struct Object
{
template< class Type >
static
void destroy( Type* p ) { delete p; }
template< class Type, class... Args>
static
auto create_shared( Args&&... args )
-> std::shared_ptr<Type>
{
return std::shared_ptr<Type>(
new Type( std::forward<Args>( args )... ),
&destroy<Type>
);
}
};
class Smart
{
friend class Object;
protected:
virtual ~Smart() {}
Smart( int ) {}
};
//Smart x; //! Nope.
struct Blah
{
//Smart x; //! Nope, sort of.
};
auto main()
-> int
{
//Smart x; //! Nope.
//new Blah; //!Can't delete.
//new Smart( 42 ); // Can't new.
Object::create_shared<Smart>( 42 ); // OK, std::shared_ptr
}
One problem with this approach is that the standard library's make_shared doesn't support a custom deleter, and shared_ptr doesn't use the common deleter of unique_ptr. One may hope that perhaps this will be rectified in future standard.
Disclaimer: I just wrote this for this answer, it's not been extensively tested. But I did this in old times with C++98, then with a macro for the create-functionality. So the principle is known to be sound.
The problem with this idea is that in the smart pointer world, T* is just a shorthand for optional<T&>. It no longer implies memory management, and as a result it becomes a safe idiom to identify an optional non-owned parameter.

Efficient ways to initialize class members; both heap and stack allocated

Assume we have the following:
//! SomeClass.hpp
class
{
public:
SomeClass( void );
~SomeClass( void )
{
delete mFoo;
delete mBar;
}
...
private:
Foo* mFoo;
Bar* mBar;
StackObj mStackFoo;
};
//! SomeClass.cpp
SomeClass::SomeClass( void )
{
mFoo = new Foo;
mBar = new Bar;
mStackFoo = StackObj( ... );
}
Now, when we initialize the pointers, my understanding is that the constructor will create unnecessary copies of SomeClass' members, thus allocating and then deallocating memory simply for the sake of allocating memory.
It's common to use initializer lists, coupled with a separate initialization function (for heap allocated memory) as a method to avoid this. Say SomeClass has a private member function defined as void initHeapMem( void ). Then we can do,
SomeClass::SomeClass( void )
: mFoo( NULL ),
mBar( NULL ),
mStackFoo( ... )
{
initHeapMem();
}
void SomeClass::initHeapMem( void )
{
mFoo = new Foo;
mBar = new Bar;
}
Naturally, this somewhat fixes the problem. The issue here I believe is that there's still the overhead of another function call being performed.
The reason why we can't use initialization lists for raw pointers is because they're not thread safe. If something goes wrong, and the program throws an exception, there will still be a memory leak. Note: this is according to what I've read, my apologies if this is wrong.
So, with boost/C++11, we can use smart pointers from an #include <tr1/memory> directive in the header file ( assuming we're using STL ).
If we were to use, say, std::unique_ptr< T >, then we'd have Bar* mBar and Foo* mFoo replaced with:
std::unique_ptr< Foo > mFoo;
std::unique_ptr< Bar > mBar;
Which would then allow us to do,
SomeClass::SomeClass( void )
mFoo( new Foo ),
mBar( new Bar ),
mStackFoo( ... )
{
}
Since the smart pointer effectively wraps the memory allocation in its own constructor.
While this is a nice solution, I personally am not one to use smart pointers for every heap object I create, and I know there are others in the C++ community who feel the same way.
tl;dr
With all of that out of the way, what I'm really wondering is if there are any more efficient alternatives to initializing class members within an object (especially with the advent of C++11), apart from the ones I listed above.
unique_ptr is the right solution here. It has several advantages:
It explicitly documents ownership. One of the issues with raw pointers is that they don’t indicate anything about who owns them. With unique_ptr you have a single owner, and must explicitly move ownership should you want to transfer it.
It has essentially no overhead; the only thing unique_ptr does is invoke the deleter, which you were going to do anyway. Now you have the performance benefits of deterministic memory behaviour without the effort of manual memory management.
It makes thread- and exception-safety much easier to attain, thanks to RAII. That means less fretting about instruction order, and less explicit cleanup code. You get the benefits of exceptions without all of the problems that caused them to be avoided in so much C++03 code.
shared_ptr is in my experience needed much less often than unique_ptr. Shared ownership is useful mainly when you have an immutable resource such as a texture or audio file, where loading and copying are both expensive, but which you want to unload when it’s not in use. shared_ptr also imposes the overhead of added safety (thread-safety in particular) and reference counting.
The disadvantage, of course, is that smart pointers impose a syntactic overhead. They are not as “native” as raw pointers. For that, you have typedef, auto, decltype, and rolling your own convenience functions such as make_unique.
Why can't you do this?
SomeClass::SomeClass( void ) :
mFoo(new Foo)
, mBar(new Bar)
{
}
They are raw pointers and no unnecessary copies are created.
I should also point out that the reason you use initializer lists is so that the object is in a valid state (that is, all members have valid values) when the constructor body is executed.
SomeClass::SomeClass( void )
{
//before this point, mFoo and mBar's values are unpredictable
mFoo = new Foo;
mBar = new Bar;
}
Regarding exceptions, the destructor of SomeClass will not be called ONLY if the exception is thrown inside the constructor itself.
Finally, regarding being thread safe or not, it depends on whether each thread has its own copy of SomeClass or not and whether SomeClass contains static members that are being written to.

transferring object ownership on std::allocator rebind

I have a Visual Studio 2008 C++ application where I am implementing a replacement for the standard allocator used in containers like std::vector. But, I've run in to an issue. My implementation relies on the allocator owning a handle to a resource. In the case where the rebind feature is used, I would need to transfer ownership of the handle to the new allocator. Something like this:
template< class T >
class MyAllocator
{
public:
template< class U >
explicit MyAllocator( const MyAllocator< U >& other ) throw()
: h_( other.Detach() ) // can't do this to a `const`
{
};
// ...
private:
HANDLE Detach()
{
HANDLE h = h_;
h_ = NULL;
return h;
};
HANDLE h_;
}; // class MyAllocator
Unfortunately, I can't relieve the old allocator of the handle ownership because it is const. If I remove const from the rebind constructor, then the containers won't accept it.
error C2558: class 'MyAllocator<T>' : no copy constructor available or copy constructor is declared 'explicit'
Is there a good way around this issue?
Without really knowing much about allocators (never needed them): Your copy ctor takes a const ref, thus promising to not to change the other object, but you attempt to change it anyway. Although there's cases where classes were designed that way (std::auto_ptr), this does seem fishy.
Syntactically, you could always declare h_ mutable, and make Detach() a const member function, but I'd seriously question the semantics of this setup, before hacking my way through the syntactic jungle using a broadsword.
What happens if you declare h_ as mutable?
You can solve this with an extra level of indirection but it's not an ideal solution. Basically, your allocator would have a pointer to a handle which would be allocated/deallocated in the constructor/destructor. The handle that it points to would be non-const throughout, so you can "move" the handle from one allocator to another. This does add some overhead to the allocator though.
I don't know your exact case but it seems that a stateful allocator that's non-trivially copyable should be carefully considered for all its implications. Is there an alternate way you can simplify its design so it doesn't have a move-only handle?
You can't transfer the ownership, because the allocator may be copied and rebound multiple times even in a single container and the resulting instances used simultaneously.
You'll have to share the resource instead. Create an indirection for the resource with reference-count. Something like:
class SharedHandle {
HANDLE h_;
int count;
SharedHandle(HANDLE h) : h_(h), count(1) {}
~SharedHandle() { CloseHandle(h_); } // or whatever to release the resource.
SharedHandle *Ref() { ++count; return this; }
void Unref() { if(!--count) delete this; }
}
and than:
explicit MyAllocator( const MyAllocator< U >& other ) throw()
: h_( other.h_->Ref() )
In addition to containers that naturally need to allocate heterogenous blocks like hash_map/unordered_map, Microsoft implementation of containers is known to allocate various strange things. When I traced allocations in one Windows application, there were many allocations of strange sizes comming from somewhere inside STL.

Ensuring pointer is not deleted

I've stumbled onto something I can't figure out, so I think I'm missing something in the greater C++ picture.
In short, my question is: how to keep a mutable, non-deletable, possibly NULL instance of an object in a class.
The longer version is:
I have the following scenario: a bunch of classes (which I can change slightly, but not thoroughly refactor), most of which need to use an object. This object, while mutable, is managed by someone else so it must not be deleted.
Some of the classes in the bunch do not need such an object - they reuse code from other classes, but through the available parameters supplied to these classes it is guaranteed that even if an object is supplied, it will not be used.
The current implementation uses a pointer-to-const-object (const Obj *). This, in turn, means all the object's methods must be const and most fields mutable. This is a messy solution since the fields declared mutable are available for inspection (so quite the opposite of the c++ lite entry here). It also only partially solves the "do-not-delete-this-here" issue (compiler does not complain but a const in front of the object is an indication).
If I used a reference to this object, I'd force some callers to create a "dummy" object and provide it to the class they are instantiating. This is also messy, besides being a waste of resources. I cannot create a global object to can stand in for a "NULL" reference due to project restrictions.
I feel that the reference is the tool I need, but I cannot refactor the classes involved to such an extent as to have the object disappear from their implementations where it is not used (it can be done, but it is not simple and it would not be fast). So I want to implement something simpler, which will just draw an alarm signal if anyone tries to misuse this object, but keeps my object mutable.
The best solution I can think of is using a const-pointer-to-object (Obj * const) - this does not make the compiler complain, but I have my mutable object and a sort-of alarm signal -through the const - in place as well.
Does anyone have a better idea ?
I've traditionally seen these kind of scenarios implemented using a shared_ptr/weak_ptr combo. See here.
The owner/deleter would get a
boost::shared_ptr<T>
Your class would get a
boost::weak_ptr<T>
To reassign the weak ptr, simply reassign the pointer:
void MyClass::Reassign(boost::weak_ptr<T> tPtr)
{
m_tPtr = tPtr;
}
To use the weak ptr, first check to see if it's still around:
void MyClass::Use()
{
boost::shared_ptr<T> m_temporarySharedPtr = m_tPtr.lock();
if (m_temporarySharedPtr)
{
//...
}
}
The weak ptr can be made "NULL" by reseting it, or assigning it to an empty shared_ptr
void MyClass::MakeNull()
{
m_tPtr.reset();
}
You can make the destructor of that object private. That will trigger compile time error on attemp to delete object. Also you should allow restcted code to delete object by using friends mechanism or member function.
You can put a wrapper around the pointer to allow modification but not deletion:
template <typename T> class Wrapper
{
public:
Wrapper(T *p=0) : pointer(p) {}
T *operator->() {return pointer;}
T const *operator->() const {return pointer;}
operator bool() const {return pointer;}
private:
T *pointer;
};
You can use this just like a pointer to the template type in some contexts, but can't call delete on it. The wrapped type must be a struct or class type (i.e. a type where -> makes sense). Then one of your classes that uses, but doesn't manage the lifetime of, the object would look a bit like this:
class User
{
public:
void Assign(Object *o) {object = o;}
void UseObject() {if (object) object->Use();}
private:
Wrapper<Object> object;
};
Technically, you can still get at the raw pointer, but the code to do it is very wrong-looking:
delete wrapper.operator->();
Sounds like a case for a shared_ptr.
An alternative (if allowed by your restircitons) would be to create a dummy object similar to a shared pointer to act as a wrapper between the object in question and your classes.
Your classes can attempt to delete this object if they wish, but it itself will leave the original object untouched. Overload the * operator and you can use it transparently.
something like this?...
the Obj class is an aggregation of your new class, you point at it with an Obj* cont pObj, which you set up at the creation of your new class (or leave as 0 if it's not used), you then check pObj before calling any of its functions?
if ( pObj ){ pObj->foo(); }
if the function foo's incorrectly defined as mutable then you need to fix its declaration.
your new class isn't responsible for cleaning up/deleting the Obj class.