Should I use smart pointers for my application and library? - c++

There are so much literature about smart pointers, I have read as much as I could. I just want a simple answer.
I have used raw pointer for my 3D renderer engines, and now I have to share some widgets between renderers, so here smart pointer comes. Please guide me should I update my entire software/library with smart pointer (std::shared_ptr)? What will be the cons in that case? I know the pros, just wanna know are there any cons? and what things are important that I should consider during the transformation from raw pointers to smart pointers? please be specific? Thanks.

Generally, they are a useful tool but not all tasks are suitable for a single tool. That said, here's a few things you should consider:
Learning about smart pointers is a valuable skill. Knowing them is the base for applying them when appropriate and ignoring them in the few cases they are not.
Smart pointers are more than just std::shared_ptr. There is also std::unique_ptr, also look into std::make_shared, std::make_unique (C++14) and std::enable_shared_from_this as a minimum.
When passing std::shared_ptr as parameters, make sure you don't add synchronized, superfluous reference count manipulations, e.g., use const std::shared_ptr<...>&.
Even when the standardized smart pointers are not the right tool, know how they work and create your own RAII wrappers - still better than full-blown, error-prone raw pointers.
When interfacing existing C-style APIs, you can still often use smart pointers and only hand down the raw pointer to those APIs where needed, using .get() on the smart pointer.

Much is to say about the pros of smart pointers and as other have already said I would recommend using them, where appropriate, in your applications.
When it comes to the API of libraries, I would say: It depends. If you are distributing your library in source form, then yes, you might use smart pointers in your API and your users might benefit from them. If you however want to distribute your library as DLL, smart pointers are not the right tool. That's because they are defined as templates and template classes are not distributable as DLLs. The users of your library would be forced to use the exact same compiler and template library as you did for the production of the DLL -- and that might be not what you want. Hence, for APIs of DLLs I would think twice before using smart pointers.

Related

Only plain pointers used in Qt API

I've been working with Qt for somedays and I wonder why all their API uses plain pointers instead of their own smart pointers like QSharedPointer.
Wouldn't it be more consistent to use them?
QSharedPointer is implemented since Qt 4.5. In Qt, QObjects organize themselves in object trees. When you create a QObject, with another object as the parent, the former is added to the latter's children list and destroyed in the latter's destructor. So you do not need to use QSharedPointer with its overhead.
Why should QSharedPointer be used when in Qt APIs object ownership is usually exclusive to one object? There is no need for sharing.
A more appropriate question would be why is Qt using raw pointers instead of smart pointers (be those Qt's or C++11's), and the reason for this is simple - those are new features, and even though Qt 5 has been released after C++11 (and internally employs it), rewriting everything to use smart pointers besides tedious will also result in annihilation of backward comparability of user code.
Overall, Qt APIs seem to be somewhat lacking and incoherent in this regard. For example - it is a major inconvenience that Qt's smart pointers are not supported in QtQuick, which uses its own private smart pointer implementation, so you should either have ownership managed by the QML engine or by C++, but you cannot really share across the two.

Are shared_ptr and the reference counting in iOS the same idea?

I'm not very experienced with either C++ or iOS, so I'm just curious if iOS the reference counting works basically alike in boost shared pointers and in NSObject?
From what I gather here, using ARC is very similar to using std::shared_ptr ("strong" pointers) and std::weak_ptr ("weak" pointers).
Abuse the former, and avoid the latter. Anyway, prefer std::unique_ptr if you can.
(Also, I am somewhat astonished that you had to release pointers manually when programming for iOS. In the 21st century.)
I'm not very experienced with C++ so I may be not completely correct about shared_ptr, but for me they doesn't seem alike. In Obj-C there're two options. Manual memory management - you manually increment and decrement reference counts for your objects, no magic occurs here. And new ARC which is mostly compile-time feature, while shared_ptr is just runtime implementation.

Is it possible to introduce Automatic Reference Counting (ARC) to C++?

Objective C has introduced a technology called ARC to free the developer from the burden of memory management. It sounds great, I think C++ developers would be very happy if g++ also has this feature.
ARC allows you to put the burden of memory management on the (Apple LLVM 3.0) compiler, and never think about retain, release and autorelease ever again
So, if LLVM3.0 can do that, I think g++ also can free C++ developers from the tough jobs of memory management, right?
Is there any difficulties to introduce ARC to C++?
What I mean is: If we don't use smart pointers, we just use new/new[], is it possible for a compiler to do something for us to prevent memory leaks? For example, change the new to a smart pointer automatically?
C++ has the concept of Resource Allocation is Initialization(RAII) & intelligent use of this method saves you from explicit resource management.
C++ already provides shared_ptr which provides reference counting.
Also, there are a host of other Smart pointers which employ RAII to make your life easier in C++.
This is a good question. ARC is much more than just an implementation of smart pointers. It is also different from garbage collection, in that it does give you full control over memory management.
In ARC you know exactly when objects are going to be released. The reason people think is isn't true, is that there's no explicit "release" call that you write. But you know when the compiler will insert one. And it's not in some garbage collection step, it's inline when objects are considered no longer needed.
It contains a compiler step that analyzes the code and tries to find any redundant sequences of incrementing and decrementing reference counts. This could probably be achieved by an optimizing C++ compiler if it was given a smart pointer implementation that its optimizer could see through.
ARC also relies on the semantics of objective c. Firstly, pointers are annotated to say whether they are strong or weak. This could also be done in C++, just by having two different pointer classes (or using smart and vanilla pointers). Secondly, it relies on naming conventions for objective c methods to know whether their return values should be implicitly weak or strong, which means it can work alongside non-ARC code (ARC needs to know if your non-ARC code intended to return an object with a +1 reference count, for example). If your "C ARC" didn't sit alongside non-"C ARC" code you wouldn't need this.
The last thing that ARC gives you, is really good analysis of your code to say where it thinks leaks may be, at compile time. This would be difficult to add to C++ code, but could be added into the C++ compiler.
There's no need. We have shared pointers that do this for us. In fact, we have a range of pointer types for a variety of different circumstances, but shared pointers mimic exactly what ARC is doing.
See:
std::shared_ptr<>
boost::shared_ptr<>
Recently I wrote some Objective-C++ code using Clang and was surprised to find that Objective-C pointers were actually handled as non-POD types in C++ that I could use in my C++ classes without issues.
They were actually freed automatically in my destructors!
I used this to store weak references in std::vectors because I couldn't think of a way to hold an NSArrary of weak references..
Anyways, it seems to me like Clang implements ARC in Objective-C by emulating C++ RAII and smart pointers in Objective-C. When you think about it, every NSObject* in ARC is just a smart pointer (intrusive_ptr from Boost) in C++.
The only difference I can see between ARC and smart pointers is that ARC is built into the language. They have the same semantics besides that.
One of the reasons C++ is used at all is full control over memory management. If you don't want that in a particular situation there are smart pointers to do the managing for you.
Managed memory solutions exist, but in the situation C++ is chosen rightfully (for large-scale big applications), it is not a viable option.
What's the advantage of using ARC rather than full garbage collection? There was a concrete proposal for garbage collection before the committee; in the end, it wasn't handled because of lack of time, but there seems to be a majority of the committee (if not truly a consensus) in favor of adding garbage collection to C++.
Globally, reference counting is a poor substitute for true garbage collection: it's expensive in terms of run time, and it needs special code to handle cycles. It's applicable in specific limited cases, however, and C++ offers it via std::shared_ptr, at the request of the programmer, when he knows it's applicable.
Take a look of Qt. Qt has implemented this feature by leverage the hierarchy chain. You can new a pointer and assign a parent to it, Qt will help you to manage the memory.
There are already some implementations of similar technologies for C++; e.g., Boehm-Demers-Weiser garbage collector.
C++11 has a special Application Binary Interface for anyone wishing to add her own garbage collection.
In the vast majority of cases, techniques like smart pointers can do the job of painless memory management for C++ developers.
Microsoft C++/CX has ARC for ref classes. Embarcadero has 2 C++ compilers, one of them has ARC.

smart pointers in windows programming

Excluding STL, I only found CComPtr in C++ windows programming. Is there any other types of smart pointers in windows SDK? Thanks.
First, STL's and boost's smart pointers are available on Windows and there's nothing wrong with using those.
Speaking of purely Windows stuff, COM interface pointers, with their AddRef/Release lifetime management model, readily lends itself to smart pointers. There are some smart pointer classes in Windows-specific libraries that are geared towards storing COM interface pointers. In addition to the ATL's CComPtr<>, there's _com_ptr_t<> of Microsoft Native COM, and MFC's COleDispatchDriver. The latter is hardly ever used with the advent of Native COM. With the exception of CComPtr, those are used together with type library import facilities.
In the Windows SDK (specific to ATL), there is CAutoPtr(single item allocation) and CAutoVectorPtr (array allocation).
The MSDN article states that CComPtr is designed to be used with COM objects only. Generally Boost smart pointers are commonly used as a platform-independent C++ smart pointer library. Since the concept of smart pointers isn't bound to a particular OS, there's really no need to use a smart pointer implementation bound to Windows, even if that's the only platform you plan on developing the application for.

Using boost in embedded system with memory limitation

We are using c++ to develop an application that runs in Windows CE 4 on an embedded system.
One of our constraint is that all the memory used by the application shall be allocated during startup only. We wrote a lot of containers and algorithms that are using only preallocated memory instead of allocating new one.
Do you think it is possible for us to use the boost libraries instead of our own containers in these conditions?
Any comments and/or advice are welcomed!
Thanks a lot,
Nic
We use boost for embedded systems. With boost you can pick and choose what you use. We use smart_ptr and boost::bind in all of our projects. We write software for cheap cell phones.
And if Windows CE can run on your hardware I would expect that parts of boost would be applicable.
There are parts of boost that have no allocation and you might find them useful.
I would pick and choose based on your requirements.
Like anything that you use, you need to know the costs.
You could write your own allocator for the container, which allocates from a fixed size static buffer. Depending on the usage patterns of the container the allocator could be as simple as incrementing a pointer (e.g. when you only insert stuff into the container once at app startup, and don't continuously add/remove elements.)
Replacing your containers with Boost containers is NOT a good idea. The work to make appropriate custom allocators wouldn't be that bad, but you'd be violating the spirit of your 'allocate at startup' rule. The idea behind this rule (in my experience) is generally to make sure that you don't have to deal with out of memory type situations at run-time. The idea is to make sure that you have all the memory you could possibly need RIGHT AT THE START, so that there's no possibility of any part of the system coming up short of memory later on.
If you used the Boost containers with a custom allocator, you'd suddenly have to deal with the possibility that the pool the container is allocating from could go empty, thus eliminating the purpose of the 'allocate at startup' rule.
In the situation of a limited memory device, I would avoid any kind of container more complex than a statically allocated array.
Boost is a set of libraries. Some of them are focussed on template metaprogramming. Those don't even use any memory at runtime. But your question seems to be about replacing your containers. I'd doubt that is possible except using custom allocators. But even then, it's most likely you would be using plain STL containers and not boost. Boost only provides the TR1 containers, for those compilers that do not yet include TR1.
Do not use Boost.
It is a big library and your basic memory allocation requirements are very different from those of the libraries designers.
Even if you can get a current version of Boost to work according to your requirements with custom allocators it may break with a new version of Boost.
Feel free to look at the Boost source code though for some useful ideas but use your own implementation for what you need.
I'm looking into this right now — I would like to use circular buffers, lock-free containers, and asynchronous I/O, and instead of allocating dynamic memory, I'd prefer to use memory pools.
The biggest problem I've seen so far is that shared_ptr is used in a lot of places, with no easy way to replace it with intrusive_ptr. Since shared_ptr allocates dynamic memory to keep track of the reference count, I can't use it in an embedded system.
Fixing this looks doable, but a lot of work — I have to expand the template specification of any class that contains a shared_ptr so that the specific type of shared-pointer can be changed to intrusive_ptr if desired. So now I have to consider how much work that'll be, versus how much work it'll be to write my own version of the Boost features I need. Not a pleasant place to be.
I hope someone points out why I'm wrong about this.