Handles have proper semantics other than pointers. So for me an example like this (extracted from the Rule of Zero):
class module {
public:
explicit module(std::wstring const& name)
: handle { ::LoadLibrary(name.c_str()), &::FreeLibrary } {}
// other module related functions go here
private:
using module_handle = std::unique_ptr<void, decltype(&::FreeLibrary)>;
module_handle handle;
};
using unique_ptr as an 'ownership-in-a-package' for handles is a bad example. First, it makes use of internal knowledge that the handle is a pointer type, and use this to make a unique_ptr to the basic type the "opaque" handle type builds upon.
Handles can be any type, they may be a pointer, they may be an index or who knows. Most importantly, what you have at hand (from most C API's for example) is a handle and its resource releasing function.
Is there a proper 'ownership-in-a-package' that works in handle semantics? I mean, already publicly available for one to use?
For me, unique_ptr et. al. doesn't work, I must make unnecessary assumptions about what the handle type is, when what I want is just to get an 'ownership-in-a-package' through the opaque handle type and its releasing function, solely.
It doesn't make sense for one to peer inside the handle type to make constructions upon this information. It's a handle, it should not matter.
I'll quote here the feelings of another SO user in another question's answer:
Create a specific "smart pointer" class, won't take long. Don't abuse
library classes. Handle semantics is quite different from that of a
C++ pointer; for one thing, dereferencing a HANDLE makes no sense.
One more reason to use a custom smart handle class - NULL does not
always mean an empty handle. Sometimes it's INVALID_HANDLE_VALUE,
which is not the same.
Disclaimer:
This question reformulates and builds upon this one:
Where's the proper (resource handling) Rule of Zero?
The type unique_ptr is less general than the phrase "handle", yes. But why shouldn't it be? Just one of your "handle" examples (say, the one that is an integer index), is precisely as general as unique_ptr. You can't compare one specific kind of handle with "all handles ever".
If you want a single, concrete C++ type (or type template) that is a handle without actually defining any specific handling semantics then... I can't help you. I don't think anyone tractibly could.
std::experimental::unique_resource
Related
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
I wish to create a class (class1) which contains another class (class2) as a data member. I then want class2 to know about class1 and be able to communicate with it.
I could have a reference to class1 as a member in class2 but that then means I need to provide a reference to class1 as a parameter in the constructor of class2 and use initialiser lists which I don't want. I'm trying to do this without needing the constructor to do it.
I would like for class2 to have a member function called Initialise which could take in the reference to class1, but this seems impossible without using pointers. What would people recommend here? Thanks in advance.
The code is completely simplified just to get the main idea across :
class class1
{
public:
InitialiseClass2()
{
c2.Initialise(this);
}
private:
class2 c2;
};
class class2
{
public:
Initialise(class1* c1)
{
this->c1 = c1;
}
private:
class1* c1;
};
this seems impossible without using pointers
That is incorrect. Indeed, to handle a reference to some other object, take a reference into a constructor:
class class2
{
public:
class2(class1& c1)
: c1(c1)
{}
private:
class1& c1;
};
The key here is to initialise, not assign, the reference. Whether this is possible depends on whether you can get rid of your Initialise function and settle into RAII (please do!). After that, whether this is actually a good idea depends on your use case; nowadays, you can almost certainly make ownership and lifetime semantics much clearer by using one of the smart-pointer types instead — even if it's just a std::weak_ptr.
Anyway, speaking more generally.
Are pointers "always" bad? No, of course not. I'd almost be tempted to say that managing dynamic memory yourself is "always" bad, but I won't make a generalisation.
Should you avoid them? Yes.
The difference is that the latter is a guideline to steer you away from manual memory management, and the former is an attempted prohibition.
No, using pointers in C++ is not bad at all, and I see this anti-advice over and over again. What is bad is managing pointers by yourself, unless you are creating a pointer-managing low-level entity.
Again, I shall make a very clear distinction. Using pointers is good. Very few real C++ programs can do without USING pointers. Managing pointers is bad, unless you are working on pointer manager.
A pointer can be nullptr whereas a reference must always be bound to something (and cannot be subsequently re-bound to something else).
That's the chief distinction and the primary consideration for your design choice.
Memory management of pointers can be delegated to std::shared_ptr and std::unique_ptr as appropriate.
well, I never had the need to 2 classes to have reciprocal reference and for good reasons, how do you know how to test those classes? If later you need to change something in the way the 2 classes communicates you will probably have to change code in both classes). You can workaround in many ways:
You may need in reality just 1 class ( you have broken into much classes)
You can register a Observer for a class (using a 3rd class, in that case you will end up with a pointer, but at least the 2 classes are less coupled and it is easier test them).
You can think (maybe) to a new interface that require only 1 class to call methods on the other class
You could pass a lambda (or a functor if you do not have C++11) into one of the methods of the class removing the need to a back reference
You could pass a reference of the class inside a method.
Maybe you have to few classes and in reality you need a third class than communicates with both classes.
It is possible you need a Visitor (maybe you really need multiple dispatch)
Some of the workarounds above need pointers, some not. To you the choice ;)
NOTE: However what you are doing is perfectly fine to me (I see you do some trickery only in constructors, but probably you have more omitted code, in wich case that can cause troubles to you). In my case I "register" one class into another, then after the constructor called I have only one class calling the other and not viceversa.
First of all whenever you have a circular dependency in your design think about it twice and make sure it's the way to go. Try to use the Dependency inversion principle in order to analyze and fix your dependencies.
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
Pointers are a powerful programming tool. Like any other feature in the C++ (or in any programming language in general) they have to be used when they are the right tool. In C++ additionally you have access to references which are similar to pointers in usage but with a better syntax. Additionally they can't be null. Thus they always reference a valid object.
So use pointers when you ever need to but try to avoid using raw pointers and prefer a smart pointer as alternative whenever possible. This will protect you against some trivial memory leak problems but you still have to pay attention to your object life-cycle and for each dynamically allocated object you should know clearly who create it and when/whom will release the memory allocated for the object.
Pointers (and references) are very useful in general because they could be used to pass parameters to a method by reference so you avoid passing heavy objects by value in the stack. Imagine the case for example that you have a very big array of heavy objects (which copy/= operator is time consuming) and you would like to sort these objects. One simple method is to use pointers to these objects so instead of moving the whole object during the sorting operation you just move the pointers which are very lightweight data type (size of machine address basically).
I've got some code that is using shared_ptr quite widely as the standard way to refer to a particular type of object (let's call it T) in my app. I've tried to be careful to use make_shared and std::move and const T& where I can for efficiency. Nevertheless, my code spends a great deal of time passing shared_ptrs around (the object I'm wrapping in shared_ptr is the central object of the whole caboodle). The kicker is that pretty often the shared_ptrs are pointing to an object that is used as a marker for "no value"; this object is a global instance of a particular T subclass, and it lives forever since its refcount never goes to zero.
Using a "no value" object is nice because it responds in nice ways to various methods that get sent to these objects, behaving in the way that I want "no value" to behave. However, performance metrics indicate that a huge amount of the time in my code is spent incrementing and decrementing the refcount of that global singleton object, making new shared_ptrs that refer to it and then destroying them. To wit: for a simple test case, the execution time went from 9.33 seconds to 7.35 seconds if I stuck nullptr inside the shared_ptrs to indicate "no value", instead of making them point to the global singleton T "no value" object. That's a hugely important difference; run on much larger problems, this code will soon be used to do multi-day runs on computing clusters. So I really need that speedup. But I'd really like to have my "no value" object, too, so that I don't have to put checks for nullptr all over my code, special-casing that possibility.
So. Is there a way to have my cake and eat it too? In particular, I'm imagining that I might somehow subclass shared_ptr to make a "shared_immortal_ptr" class that I could use with the "no value" object. The subclass would act just like a normal shared_ptr, but it would simply never increment or decrement its refcount, and would skip all related bookkeeping. Is such a thing possible?
I'm also considering making an inline function that would do a get() on my shared_ptrs and would substitute a pointer to the singleton immortal object if get() returned nullptr; if I used that everywhere in my code, and never used * or -> directly on my shared_ptrs, I would be insulated, I suppose.
Or is there another good solution for this situation that hasn't occurred to me?
Galik asked the central question that comes to mind regarding your containment strategy. I'll assume you've considered that and have reason to rely on shared_ptr as a communical containment strategy for which no alternative exists.
I have to suggestions which may seem controversial. What you've defined is that you need a type of shared_ptr that never has a nullptr, but std::shared_ptr doesn't do that, and I checked various versions of the STL to confirm that the customer deleter provided is not an entry point to a solution.
So, consider either making your own smart pointer, or adopting one that you change to suit your needs. The basic idea is to establish a kind of shared_ptr which can be instructed to point it's shadow pointer to a global object it doesn't own.
You have the source to std::shared_ptr. The code is uncomfortable to read. It may be difficult to work with. It is one avenue, but of course you'd copy the source, change the namespace and implement the behavior you desire.
However, one of the first things all of us did in the middle 90's when templates were first introduced to the compilers of the epoch was to begin fashioning containers and smart pointers. Smart pointers are remarkably easy to write. They're harder to design (or were), but then you have a design to model (which you've already used).
You can implement the basic interface of shared_ptr to create a drop in replacement. If you used typedefs well, there should be a limited few places you'd have to change, but at least a search and replace would work reasonably well.
These are the two means I'm suggesting, both ending up with the same feature. Either adopt shared_ptr from the library, or make one from scratch. You'd be surprised how quickly you can fashion a replacement.
If you adopt std::shared_ptr, the main theme would be to understand how shared_ptr determines it should decrement. In most implementations shared_ptr must reference a node, which in my version it calls a control block (_Ref). The node owns the object to be deleted when the reference count reaches zero, but naturally shared_ptr skips that if _Ref is null. However, operators like -> and *, or the get function, don't bother checking _Ref, they just return the shadow, or _Ptr in my version.
Now, _Ptr will be set to nullptr (or 0 in my source) when a reset is called. Reset is called when assigning to another object or pointer, so this works even if using assignment to nullptr. The point is, that for this new type of shared_ptr you need, you could simply change the behavior such that whenever that happens (a reset to nullptr), you set _Ptr, the shadow pointer in shared_ptr, to the "no value global" object's address.
All uses of *,get or -> will return the _Ptr of that no value object, and will correctly behave when used in another assignment, or reset is called again, because those functions don't rely upon the shadow pointer to act upon the node, and since in this special condition that node (or control block) will be nullptr, the rest of shared_ptr would behave as though it was pointing to nullptr correctly - that is, not deleting the global object.
Obviously this sounds crazy to alter std::pointer to such application specific behavior, but frankly that's what performance work tends to make us do; otherwise strange things, like abandoning C++ occasionally in order to obtain the more raw speed of C, or assembler.
Modifying std::shared_ptr source, taken as a copy for this special purpose, is not what I would choose (and, factually, I've faced other versions of your situation, so I have made this choice several times over decades).
To that end, I suggest you build a policy based smart pointer. I find it odd I suggested this earlier on another post today (or yesterday, it's 1:40am).
I refer to Alexandrescu's book from 2001 (I think it was Modern C++...and some words I don't recall). In that he presented loki, which included a policy based smart pointer design, which is still published and freely available on his website.
The idea should have been incorporated into shared_ptr, in my opinion.
Policy based design is implemented as the paradigm of a template class deriving from one or more of it's parameters, like this:
template< typename T, typename B >
class TopClass : public B {};
In this way, you can provide B, from which the object is built. Now, B may have the same construction, it may also be a policy level which derives from it's second parameter (or multiple derivations, however the design works).
Layers can be combined to implement unique behaviors in various categories.
For example:
std::shared_ptr and std::weak_ptrare separate classes which interact as a family with others (the nodes or control blocks) to provide smart pointer service. However, in a design I used several times, these two were built by the same top level template class. The difference between a shared_ptr and a weak_ptr in that design was the attachment policy offered in the second parameter to the template. If the type is instantiated with the weak attachment policy as the second parameter, it's a weak pointer. If it's given a strong attachment policy, it's a smart pointer.
Once you create a policy designed template, you can introduce layers not in the original design (expanding it), or to "intercept" behavior and specialize it like the one you currently require - without corrupting the original code or design.
The smart pointer library I developed had high performance requirements, along with a number of other options including custom memory allocation and automatic locking services to make writing to smart pointers thread safe (which std::shared_ptr doesn't provide). The interface and much of the code is shared, yet several different kinds of smart pointers could be fashioned simply by selecting different policies. To change behavior, a new policy could be inserted without altering the existing code. At present, I use both std::shared_ptr (which I used when it was in boost years ago) and the MetaPtr library I developed years ago, the latter when I need high performance or flexible options, like yours.
If std::shared_ptr had been a policy based design, as loki demonstrates, you'd be able to do this with shared_ptr WITHOUT having to copy the source and move it to a new namespace.
In any event, simply creating a shared pointer which points the shadow pointer to the global object on reset to nullptr, leaving the node pointing to null, provides the behavior you described.
Windows handles are sometimes annoying to remember to clean up after (doing GDI with created pens and brushes is a great example). An RAII solution is great, but is it really that great making one full (Rule of Five) RAII class for each different type of handle? Of course not! The best I can see would be one full generic RAII class with other classes just defining what to do when the handle should be cleaned up, as well as other handle-specific aspects.
For example, a very simple module class could be defined like this (just an example):
struct Module {
Module() : handle_{nullptr} {}
Module(HMODULE hm) : handle_{hm, [](HMODULE h){FreeLibrary(h);}} {}
operator HMODULE() const {return handle_.get();}
private:
Handle<HMODULE> handle_;
};
That's all fine and dandy, and no destructor or anything is needed. Of course, though, being able to write the Handle class to not need a destructor or anything as well would be nice, too. Why not use existing RAII techniques? One idea would be to use a smart pointer to a void, but that won't work. Here's how the handles are actually declared under normal circumstances:
#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HBITMAP);
DECLARE_HANDLE(HBRUSH);
...
It actually differentiates between handle types, which is good, but it makes using a smart pointer to void impossible. What if, instead, since handles are, by definitions, pointers, the type could be extracted?
My question is whether the following is a safe assumption to make. It uses a handle to a desktop, which must be closed. Barring the differences between shared and unique pointers (e.g., FreeLibrary has its own reference counting semantics), is assuming the handle is a pointer and making a smart pointer to whatever it's pointing to okay, or should I not use smart pointers and make Handle implement the RAII aspects itself?
#include <memory>
#include <type_traits>
#include <utility>
#include <windows.h>
int main() {
using underlying_type = std::common_type<decltype(*std::declval<HDESK>())>::type;
std::shared_ptr<underlying_type> ptr{nullptr, [](HDESK desk){CloseDesktop(desk);}};
}
I believe all Windows pointers are technically pointers to internal objects inside the Windows kernel part of the system (or sometimes, possibly, to user-side objects allocated by the kernel code, or some variation on that theme).
I'm far from convinced that you should TREAT them as pointers tho'. They are only pointers in a purely technical perspective. They are no more "pointers" than C style "FILE *" is a pointer. I don't think you would suggest the use of shared_ptr<FILE*> to deal with closing files later on.
Wrapping a handle into something that cleans it up later is by all means a good idea, but I don't think using smart pointer solutions is the right solution. Using a templated system which knows how to close the handle would be the ideal.
I suppose you also would need to deal with "I want to pass this handle from here to somewhere else" in some good way that works for all involved - e.g. you have a function that fetches resources in some way, and it returns handles to those resources - do you return an already wrapped object, and if so, how does the copy work?
What if you need to save a copy of a handle before using another one (e.g. save current pen, then set a custom one, then restore)?
One approach you could take is to use a template class:
template<typename H, BOOL(WINAPI *Releaser)(H)>
class Handle
{
private:
H m_handle;
public:
Handle(H handle) : m_handle(handle) { }
~Handle() { (*Releaser)(m_handle); }
};
typedef Handle<HANDLE,&::CloseHandle> RAIIHANDLE;
typedef Handle<HMODULE,&::FreeLibrary> RAIIHMODULE;
typedef Handle<HDESK,&::CloseDesktop> RAIIHDESKTOP;
If there is a HANDLE which isn't released by a function of type BOOL(WINAPI)(HANDLE), then you may have issues with this. If the releasing functions only differ by return type though, you could add that as a template parameter and still use this solution.
Technically, this ought to work perfectly well under all present versions of Windows, and it is hard to find a real reason against doing it (it is actually a very clever use of existing standard library functionality!), but I still don't like the idea because:
Handles are pointers, and Handles are not pointers. Handles are opaque types, and one should treat them as such for compatibility. Handles are pointers, and it is unlikely that handles will ever be something different, but it is possible that this will change. Also, handles may or may not have values that are valid pointer values, and they may or may not have different values under 32bit and 64bit (say INVALID_HANDLE_VALUE), or other side effects or behaviours that you maybe don't foresee now. Assuming that a handle has certain given properties may work fine for decades, but it may (in theory) mysteriously fail in some condition that you didn't think about. Admittedly, it is very unlikely to happen, but still it isn't 100% clean.
Using a smart pointer in this way doesn't follow the principle of least astonishment. Because, hey, handles aren't pointers. Having RAII built into a class that is named with an intuitive name ("Handle", "AutoHandle") will not cause anyone to raise an eyebrow.
I believe that both unique_ptr and shared_ptr allow you to provide custom deleter. Which I believe is just what you need to correctly manage lifetime of handles.
Does Boost, or anything else, contain a container will act like a shared pointer but allow me to control what happens to the shared 'resource' at the end of it's life? I want to encapsulate an object that can be handed around but, when no longer needed can be closed in a context defined way.
For example, I might want to create and pass around a file handle knowing that when it goes out of scope, the file will be closed automatically, but I don't want to delete the handle.
I could implement it myself, but would rather not get into that if the framework already exists - someone has no doubt done it better. I can't use boost::shared_ptr, at least not in it's normal form, as the resource should not be deleted at end of life.
Are you aware that std::shared_ptr can take a custom deleter class? This need not actually use "delete" or "free", but could easily use some other sort of mechanism (such as a reference counting mechanism's release and so on).
Here's a dead simple example for you:
std::shared_ptr<FILE> foo(fopen("la", "r"), fclose);
The deleter just needs to be a function that takes the pointer type that the shared_ptr wraps. In this case, whenfoo goes out of scope, shared_ptr will close the file for you. (Note: this isn't a totally sensible implementation, because no error values are checked. It is just an example).
If you are using a compiler that supports the C++11 std::shared_ptr, one of the constructors takes a custom "deleter" function. This would allow you to write your own function for "releasing" the resources.
EDIT -
I forgot that std::shared_ptr was actually in the TR1 update to C++, so if your compiler supports TR1 you should be in good shape.
Since you can't use Boost or the std::shared_ptr, you could write a smart pointer be it shared or unique that has custom Deleter.
I'm confused by the choices for COM smart pointers classes for C++ programming:
There's three four I'm aware of:
CCOMPtr from ATL
_com_ptr_t from the MS Com Support Classes
TComInterface (because I'm using C++Builder 2009)
CCOMQIPtr, (which I'd previously forgotten)
I've read about the error vs. exception handling differences of the first two, but TComInterface seems totally undocumented. Both the first two seem to have gotchas or 'unexpected' behaviour, from what I can find.
Ideally, I'd like something that's clean and modern C++, but boost::com doesn't exist as far as I know...
I need to control an application from another vendor. They provide a COM interface via a TLB file.
If you are using the type-library import stuff, it will generate code based upon _com_ptr_t and the related COM Support Classes. Go ahead and use those if you are just using stuff from those libraries.
If you are writing ATL-based code, then use CCOMPtr and the other ATL-based classes.
Things may get ugly if you need to mix-and-match both types, but you should probably just get comfortable with both and use whichever makes the most sense for whatever you are doing at the time.
The nice thing is that you have the source for all of these things, so you don't have to rely only on the documentation (which has not been getting much care since .NET appeared).
Since you are asking for "clean and modern" C++ style, and giving boost as an example, I'll throw in two more: std/boost::shared_ptr and boost::intrusive_ptr. The intrusive_ptr is obviously the more natural choice, since COM objects have an intrusive reference counting mechanism. shared_ptr works just as well, you only need to use a custom deleter that calls IUnknown::Release(), and a small object generator function that does the IUnknown::AddRef() and returns the smart pointer.
I usually go with the intrusive_ptr, so I'm going to explain that in more detail. First, of course, intrusive_ptr_add_ref and intrusive_ptr_release have to be implemented for all IUnknowns. The intrusive_ptr constructor already has a handy feature to skip adding another reference, since many COM functions will do the AddRef() for you.
Now there's one problem with this approach: the intrusive_ptr does not expose its underlying bare pointer like some of the other COM pointers. This is a problem since a common way to create COM objects is by passing a pointer to a pointer to some creation function in another object. Since you cannot pass the intrusive_ptr into these functions, you end up with clumsy temporary bare-pointers that are used to initialize the intrusive_ptr. This is not very elegant, let alone exception-safe (if you need this at all with COM code, which naturally doesn't throw exceptions. I translate COM errors into exceptions though.)
So what I do here is use another tool function that turns a function that takes any com function and returns a callable where any parameter that was a pointer-to-pointer-to-T can either be that or a reference to an intrusive_ptr. Anything else is just like the "input function". These functions then do all the converting between T** and intrusive_ptr& for me. For example, HRESULT CreateBuffer(IBuffer** bufferOut, int size) becomes a callable with the signature HRESULT CreateBuffer(instrusive_ptr<IBuffer>& bufferOut, int size). They are a bit tedious to write for "all" arities, unless you have a code generator, lots of patience, or I presume, variadic templates. But once you have them, it actually makes working with COM very nice.
I've used the first two, CComPtr and _com_ptr_t.
It sounds like you've already read about the difference with errors and exception handling, so pick the one you liked best, or that fits in most consistently with the rest of the error handling in your code.
As kenny mentioned you can use CComPtr to manage pointers to the COM Interfaces. This class is well documented (see msdn) and uses automatic reference counting, what, I suppose, you are wanting.
OTOH, Rob question is important: do you really uses COM Interfaces? For just pointers you can use smart pointers from STL or boost libraries which anyway better (in general) than CComPtr.