I have had a template for some time which wrappers a C library FILE*. It's a fairly classic implementation of a shared pointer to a wrapper class for the FILE*. The reasoning behind using my own custom shared pointer is to provide free function replacements for some of the C library FILE* free functions, in order to allow me to do a drop-in replacement of legacy code that works with FILE*.
The implementation that I have uses an inner wrapper that guarantees that when it is deleted, the owned FILE* is closed. RAII.
However, I've come into the need to create a similar system to handle the case where I want the underlying FILE* to be flushed & truncated, rather than closed when the last FILE* holder is destroyed. That is to say, I have an open FILE* of the original guaranteed-to-close type, but wish to hand out an unowned copy of the FILE* to another object that is going to guarantee that when it's last instance is destroyed, that it will flush & truncate the FILE* rather than close it, hence leaving me with the underlying FILE* in an open state, but with the contents of the stream flushed to disk (and the file size reflecting only valid contents).
I have solved this trivially for compile time polymorphism. But I need some way to supply runtime polymorphism, and I really don't want to put yet-another-layer-of-indirection into this scenario (i.e. if I used a polymorphic pointer to either an auto-close or auto-flush FILE* wrapper, I'd be golden - but I really want to keep the same depth I have now and hide the polymorphism inside the custom shared pointer implementation).
Basically, if I have a:
template <class WrapperT>
class FilePointerT
{
public:
// omitted: create, destroy, manipulate the underlying wrappered FILE*
private:
WrapperT * m_pFileWrapper;
ReferenceCount m_rc;
}
Obviously, tons of details omitted. Suffice it to say that when the last one of these objects is deleted, it deletes the last m_pFileWrapper (in fact, if I were rewriting this code, I'd probably use a boost::shared_ptr).
Regardless, the real issue here is I am stumped on how to have a FilePointerT<WrapperT> whose WrapperT can vary, but can then be used in code as if they were all the same (which, after all, they are, since the implementation of WrapperT has zero affect on the structure and interface of FilePointerT (essentially a pimpl).
What can I declare that can possibly hold any FilePointerT<WrapperT> for any WrapperT?
Or, how can I change the definition of FilePointerT in order to allow me to supply specific WrapperT?
Can't you simply use std::shared_ptr<FILE *, deleter_function> ? Provide ordinary overloads for the free functions, no funny template malarky.
You can use type erasure to treat all versions of FilePointerT transparently. As the above poster mentions I'd also go for a shared_ptr approach, in fact the deleter isn't even part of the shared_ptr signature so you'll be able to vary the deleter while keeping the type constant.
For what it's worth, what I ended up doing is to embed the wrapper into the FilePointer class, instead of making it part of its type.
class FilePointer
{
public:
// create using a file wrapper (which will handle policy issues)
FilePointer(FileWrapper * pfw) : m_pFileWrapper(pfw) { }
protected:
FileWrapper * m_pFileWrapper; // wrapper has close/flush policy
ReferenceCount m_references; // reference count
};
Then the file pointer just delegates the real work to the wrapper, and the wrapper implements the needed policy, and code can be written to consume FilePointer(s).
There are obviously other ways to do this, but that's what I went with.
Related
I find it convenient to (and have a lot of code which) wrappers some storage object in an allocation adapter, and then this allocation adapter is used commonly to scope the guaranteed backstore in a managing object for its lifetime, which is normally the lifetime of the function call.
This seems to be using a nonstandard VisualStudio extension, however, and I'm curious as to what is a better paradigm and why..
e.g. a lot of our code still uses CString. One of the features of a CString is the ability to lock its contents so that you can take a non-const pointer into the underlying buffer and manipulate it directly - a'la C library functions.
This makes it very easy to use a CString for its automatic resource management, but still interface to legacy libraries / code which needed a writable character buffer. However, locking the buffer is not itself an RAII operation, so I made an RAII class to perform that function (like taking on a lock):
// replaces each occurrence of any of the given list of characters with a specified replacement character in-place
inline void ReplaceAll(CStringW & str, const wchar_t * chsOld, const wchar_t chNew)
{
ReplaceAll(make_autobuffer(str), chsOld, chNew);
}
The code behind make_autobuffer is rather long-winded, but the idea boils down to returning an object that holds a lock on the underlying string's buffer, and will ask the str to release that buffer lock on its destruction, thus releasing the buffer back to control by the CString.
This is a trivial idea, and the implementation is fairly trivial as well (lots of boiler plate to make it robust wrt wide/narrow strings, and variations that take a fixed buffer size or not, and some debugging helpers, etc.).
But more generally speaking, I have often found it very useful to have a class which takes a non-const reference to an instance of something, and wrappers that instance in some sort of mutable adapter layer, and then releases the underlying entity upon termination.
The question is whether there is a better way to accomplish this than having to create a named variable to do the adaptation:
// replaces each occurrence of any of the given list of characters with a specified replacement character in-place
inline void ReplaceAll(CStringW & str, const wchar_t * chsOld, const wchar_t chNew)
{
auto adapter = make_autobuffer(str);
ReplaceAll(adapter, chsOld, chNew);
}
This works, and doesn't violate the standard. I'm no longer trying to pass a non-const object by ref from a temp object - since I've forced the temp object into being less temporary by naming it.
But... that seems silly. At the end of the day, doing the above doesn't change the meaning as far as I can tell. And if the VisualStudio allowance was non-standard, then is there a better standard way that isn't so silly?
But... that seems silly. At the end of the day, doing the above doesn't change the meaning as far as I can tell.
Yes it is quite different. However, had you written
auto const& adapter = make_autobuffer(str);
ReplaceAll(adapter, chsOld, chNew);
that would be the same as
ReplaceAll(make_autobuffer(str), chsOld, chNew);
(consider what happens if the copy constructor isn't accessible for the return type of make_autobuffer).
WARNING I just realized we know nothing about what make_autobuffer actually returns. Let me state my assumption: I assume you return a RAII wrapper class with implicit conversion to the parameter type expected by the ReplaceAll function (e.g. char const*¹)
Onto the "main question" - this seems pretty vague. I think you're talking about the MSVC non-standard extension to "lifetime extensions of temporaries when bound to non-const references".
I don't see where that comes in in the code you showed, for the simple reason that you show make_autobuffer being called inside the parameter list. As such, the temporary is guaranteed to exist until after that function call returned anyways, no need to bind/name things to achieve that. Not even in standard c++03.
If you wish to extend the lock to beyond the function call, then yes, name the RAII handle.
Similar design points in the standard library (and Boost counterparts):
std::lock_guard needs to be named to keep the lock beyond the end of the containing full expression
std::async returns a future that needs to be kept in a named variable if you want any semblance of actual async execution (otherwise, the destructor of the future still causes immediate blocking execution)
¹ LPCTSTR in your region?
Ultimately what I chose to do to solve this was to change from using Wrapper & to Wrapper (by copy / move).
Passing a non-const wrapper by ref is a clear violation of C++ argument rules. Having to declare it explicitly was annoying. Passing it by value meant that I could take advantage of Cx11's move rules and maintain no copies for a CStringAutoBuffer (and other similar types of temporary wrapper objects), but still create one on the fly without having to explicitly name one locally.
This preserves const correctness as well.
Overall, a happy resolution to this genre of issue. :)
I am trying to write a simple game using C++ and SDL. My question is, what is the best practice to store class member variables.
MyObject obj;
MyObject* obj;
I read a lot about eliminating pointers as much as possible in similar questions, but I remember that few years back in some books I read they used it a lot (for all non trivial objects) . Another thing is that SDL returns pointers in many of its functions and therefor I would have to use "*" a lot when working with SDL objects.
Also am I right when I think the only way to initialize the first one using other than default constructor is through initializer list?
Generally, using value members is preferred over pointer members. However, there are some exceptions, e.g. (this list is probably incomplete and only contains reason I could come up with immediately):
When the members are huge (use sizeof(MyObject) to find out), the difference often doesn't matter for the access and stack size may be a concern.
When the objects come from another source, e.g., when there are factory function creating pointers, there is often no alternative to store the objects.
If the dynamic type of the object isn't known, using a pointer is generally the only alternative. However, this shouldn't be as common as it often is.
When there are more complicated relations than direct owner, e.g., if an object is shared between different objects, using a pointer is the most reasonable approach.
In all of these case you wouldn't use a pointer directly but rather a suitable smart pointer. For example, for 1. you might want to use a std::unique_ptr<MyObject> and for 4. a std::shared_ptr<MyObject> is the best alternative. For 2. you might need to use one of these smart pointer templates combined with a suitable deleter function to deal with the appropriate clean-up (e.g. for a FILE* obtained from fopen() you'd use fclose() as a deleter function; of course, this is a made up example as in C++ you would use I/O streams anyway).
In general, I normally initialize my objects entirely in the member initializer list, independent on how the members are represented exactly. However, yes, if you member objects require constructor arguments, these need to be passed from a member initializer list.
First I would like to say that I completely agree with Dietmar Kühl and Mats Petersson answer. However, you have also to take on account that SDL is a pure C library where the majority of the API functions expect C pointers of structs that can own big chunks of data. So you should not allocate them on stack (you shoud use new operator to allocate them on the heap). Furthermore, because C language does not contain smart pointers, you need to use std::unique_ptr::get() to recover the C pointer that std::unique_ptr owns before sending it to SDL API functions. This can be quite dangerous because you have to make sure that the std::unique_ptr does not get out of scope while SDL is using the C pointer (similar problem with std::share_ptr). Otherwise you will get seg fault because std::unique_ptr will delete the C pointer while SDL is using it.
Whenever you need to call pure C libraries inside a C++ program, I recommend the use of RAII. The main idea is that you create a small wrapper class that owns the C pointer and also calls the SDL API functions for you. Then you use the class destructor to delete all your C pointers.
Example:
class SDLAudioWrap {
public:
SDLAudioWrap() { // constructor
// allocate SDL_AudioSpec
}
~SDLAudioWrap() { // destructor
// free SDL_AudioSpec
}
// here you wrap all SDL API functions that involve
// SDL_AudioSpec and that you will use in your program
// It is quite simple
void SDL_do_some_stuff() {
SDL_do_some_stuff(ptr); // original C function
// SDL_do_some_stuff(SDL_AudioSpec* ptr)
}
private:
SDL_AudioSpec* ptr;
}
Now your program is exception safe and you don't have the possible issue of having smart pointers deleting your C pointer while SDL is using it.
UPDATE 1: I forget to mention that because SDL is a C library, you will need a custom deleter class in order to proper manage their C structs using smart pointers.
Concrete example: GSL GNU scientific library. Integration routine requires the allocation of a struct called "gsl_integration_workspace". In this case, you can use the following code to ensure that your code is exception safe
auto deleter= [](gsl_integration_workspace* ptr) {
gsl_integration_workspace_free(ptr);
};
std::unique_ptr<gsl_integration_workspace, decltype(deleter)> ptr4 (
gsl_integration_workspace_alloc (2000), deleter);
Another reason why I prefer wrapper classes
In case of initialization, it depends on what the options are, but yes, a common way is to use an initializer list.
The "don't use pointers unless you have to" is good advice in general. Of course, there are times when you have to - for example when an object is being returned by an API!
Also, using new will waste quite a bit of memory and CPU-time if MyObject is small. Each object created with new has an overhead of around 16-48 bytes in a typical modern OS, so if your object is only a couple of simple types, then you may well have more overhead than actual storage. In a largeer application, this can easily add up to a huge amount. And of course, a call to new or delete will most likely take some hundreds or thousands of cycles (above and beyond the time used in the constructor). So, you end up with code that runs slower and takes more memory - and of course, there's always some risk that you mess up and have memory leaks, causing your program to potentially crash due to out of memory, when it's not REALLY out of memory.
And as that famous "Murphy's law states", these things just have to happen at the worst possible and most annoying times - when you have just done some really good work, or when you've just succeeded at a level in a game, or something. So avoiding those risks whenever possible is definitely a good idea.
Well, creating the object is a lot better than using pointers because it's less error prone. Your code doesn't describe it well.
MyObj* foo;
foo = new MyObj;
foo->CanDoStuff(stuff);
//Later when foo is not needed
delete foo;
The other way is
MyObj foo;
foo.CanDoStuff(stuff);
less memory management but really it's up to you.
As the previous answers claimed the "don't use pointers unless you have to" is a good advise for general programming but then there are many issues that could finally make you select the pointers choice. Furthermore, in you initial question you are not considering the option of using references. So you can face three types of variable members in a class:
MyObject obj;
MyObject* obj;
MyObject& obj;
I use to always consider the reference option rather than the pointer one because you don't need to take care about if the pointer is NULL or not.
Also, as Dietmar Kühl pointed, a good reason for selecting pointers is:
If the dynamic type of the object isn't known, using a pointer is
generally the only alternative. However, this shouldn't be as common
as it often is.
I think this point is of particular importance when you are working on a big project. If you have many own classes, arranged in many source files and you use them in many parts of your code you will come up with long compilation times. If you use normal class instances (instead of pointers or references) a simple change in one of the header file of your classes will infer in the recompilation of all the classes that include this modified class. One possible solution for this issue is to use the concept of Forward declaration, which make use of pointers or references (you can find more info here).
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.
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
I often come accross the problem that I have a class that has a pair of Register/Unregister-kind-of-methods. e.g.:
class Log {
public:
void AddSink( ostream & Sink );
void RemoveSink( ostream & Sink );
};
This applies to several different cases, like the Observer pattern or related stuff. My concern is, how safe is that? From a previous question I know, that I cannot safely derive object identity from that reference. This approach returns an iterator to the caller, that they have to pass to the unregister method, but this exposes implementation details (the iterator type), so I don't like it. I could return an integer handle, but that would require a lot of extra internal managment (what is the smallest free handle?). How do you go about this?
You are safe unless the client object has two derivations of ostream without using virtual inheritance.
In short, that is the fault of the user -- they should not be multiply inheriting an interface class twice in two different ways.
Use the address and be done with it. In these cases, I take a pointer argument rather than a reference to make it explicit that I will store the address. It also prevents implicit conversions that might kick in if you decided to take a const reference.
class Log {
public:
void AddSink( ostream* Sink );
void RemoveSink( ostream* Sink );
};
You can create an RAII object that calls AddSink in the constructor, and RemoveSink in the destructor to make this pattern exception-safe.
You could manage your objects using smart pointers and compare the pointers for equality inside your register / deregister functions.
If you only have stack allocated objects that are never copied between an register and deregister call you could also pass a pointer instead of the reference.
You could also do:
typedef iterator handle_t;
and hide the fact that your giving out internal iterators if exposing internal data structures worries you.
In your previous question, Konrad Rudolph posted an answer (that you did not accept but has the highest score), saying that everything should be fine if you use base class pointers, which you appear to do.