Which COM smart pointer classes to use? - c++

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.

Related

Is it necessarily bad to use const_cast when working with legacy libraries?

I am writing a C++ program for Linux. I use many low-level libraries such as XLib, FontConfig, Xft etc. They are all written in pure C, and in some places in my code I have this annoying problem:
I wrap C structures in RAII-friendly classes, where resources are allocated in constructors and freed in destructors. Freeing most of these resources is not just calling free(), special library functions should be used instead (::XftFontClose(), ::FcPatternDestroy() etc), so I don't see benefits of using smart pointers. Instead, I keep read-only raw pointers to library resources inside my classes and provide getter functions returning constant pointers to these resources so that they are unable to be modified outside of the classes that own them.
For example, I have a class containing a sorted list of system fonts, and I can ask this class to find and open the best font that can be used to draw a specific character:
const ::XftFont* FontHandler::findBestFont(wchar_t character);
The callers should not be able to modify the underlying object pointed to by the returned pointer, this is the task of the class' methods/destructor.
The problem is that, most of the functions I want to pass the returned pointer to look like this:
void
XftDrawStringUtf8
(XftDraw *d,
XRenderColor *color,
XftFont *font, // It is not const
int x,
int y,
XftChar8 *string,
int len);
As you can see, even if the function does not need to change the data pointed to, the pointer is not const, and the only way to make it work is to use const_cast, which is never recommended, as far as I know.
This is just a single example, but there are many such issues in the real code.
I wonder, why are these legacy libraries built in such a way? Why don't they use const pointers when they actually should be const? And what is the best way to deal with such problems?
Is it necessarily bad to use const_cast when working with legacy libraries?
No.
It's generally bad to design code that requires a lot of const_cast, because it suggests you haven't thought very carefully about mutability.
You're using libraries that were written before const-correctness was much considered, and their design shortfalls are not your fault. Adapting to them is an entirely appropriate use of const_cast.
Freeing most of these resources is not just calling free(), special library functions should be used instead(::XftFontClose(), ::FcPatternDestroy() etc.,) so I don't see benefits of using smart pointers
You know you can use smart pointers with custom deleters, right? The benefit - that you don't have to implement five special methods in each class - is still there.
At most, consider writing a rule-of-zero wrapper type storing a std::unique_ptr (or std::shared_ptr, or whatever) with a custom deleter. It's a lot less typing, and way fewer opportunities for annoying bugs.

Splitted interface of library (ChessGame with Figures etc) vs user's law to delete every pointer

Sometimes it's convenient to split interface of some system/library in more than one class.
For example, consider idea of library for playing Chess. Its interface would use (and deliver to players) different object for every single game and - during game - another object for every figure.
In Java there wouldn't be such a problem. But in C++, a library user can delete (or make attempt to delete) every pointer he'll get. Even shared_ptr/weak_ptr.
What do you think about such situations? Should I use in my interface wrapping classes that deleting isn't dangerous?
What is an usual way for such dilemmas?
Is there a way that STL smart pointers would help? I heard that they should be used always and only to express ownership, so they seem to have nothing to do with this issue (Chess is owner of SingleGame, SingleGame is owner of every Figure).
PS did I use correct tags/subject?
You can't stop a user from breaking stuff. As others have suggested, use smart pointers. With C++11, there is no reason not to use them in new code. If the user still breaks it, that's their fault. You can't design a library that is completely foolproof. You can just do your best to disuade foolish behavior.
As others have said, smart pointers (or other RAII schemes) are often a great idea. They can clearly indicate ownership and at the same time provide an automatic mechanism for managing it. Try using such if you can.
But really, no reasonable C++ programmer should be blindly calling delete on every pointer they get. When they use a library/API/whatever which returns a pointer/handle/resource/etc they should be reading its documentation to tell them whether or not they will be responsible for deallocation and if so then when technique should be used.
So at a minimum, just make sure your public interface clearly indicates when ownership is passed to the caller and what method they should use for cleanup.

Explicitly expressing ownership in Delphi

I'm primarily a C++ programmer, and I've grown used to having class templates like std::unique_ptr, std::shared_ptr, etc for expressing ownership of my objects. Does Delphi have anything that is similar in its standard library? Are there any best-practices out there for expressing object ownership that I should be following as I write my code?
Edit: Since C++11 became standard, there are two lightweight helper classes, std::shared_ptr and std::unique_ptr.
If I create a variable of type std::shared_ptr<int>, it represents a pointer to an int with shared ownership: under the hood is reference-counted, and when the ref-count reaches zero then the pointer is automatically freed. This type expresses a kind of "shared ownership", where many objects share the responsibility of destroying the resource when they are done with it.
In contrast, std::unique_ptr expresses single ownership. When the unique_ptr goes out of scope, the resource is automatically freed. std::unique_ptr cannot be copied: there can be exactly one object owning this resource at a time, and there is exactly one object who is responsible to clean the object up.
Contrast these lightweight classes with a naked pointer to int, where it can represent either shared ownership, unique ownership, or it can just be a reference to an object somewhere else! The type tells you nothing.
My question is: as Delphi supports holding references to objects, are there any mechanisms for explicitly stating "I am the sole owner of this object, when I'm done with it, I will free it", vs "I am merely keeping a reference to this object around for the purpose of interacting with it, but somebody else will clean it up" vs "I share this object with many other objects, and whoever has it last gets to clean it up."
I know that Collections.Generics has different collections such as TList vs TObjectList, where TObjectList will free the members stored within it, but TList won't. You can say that TObjectList "owns" it's elements, whereas TList doesn't. This is the essence of my question, really. When designing my own classes, are there ways of directly expressing these kinds of ownership issues within the language? Or are there any best practices/naming conventions that are common amongst developers?
I am not aware of any language constructs that can help, nor of any "standard naming conventions".
However, long ago, I have adopted the following naming convention to make it easier to check whether classes clean up behind themselves properly:
As per the standard Delphi convention all field names start with an "F".
Object references for which the class has / takes on life time management responsibility, start with "FMy".
Interface references the class should release explicitly, by setting the reference to nil in the destructor (for performance, to break a cyclic dependency, etc.) start with "FMi"
Very crude, but it works, and has helped a lot when going through code you haven't seen in a while to prevent those "Wait, shouldn't that reference be freed or nilled?" searches.
std::unique_ptr cannot be copied: there can be exactly one object owning this resource at a time
In the Delphi language, there is no type nor mechanism that prevents to share 'ownership'. A copy of any reference can always be made. (Read: there's nothing in Delphi that allows you to block assignment, as David nicely put it.)
When the unique_ptr goes out of scope, the resource is automatically freed.
In Delphi, this is only possible with (or via) interfaces. Delphi has no garbage collector.
And there is exactly one object who is responsible to clean the object up.
Responsibility for cleaning up you have to enforce by yourself. Or delegate that task to a(nother) framework. For example, the default Delphi VCL class TComponent implements automatic ownership (and destruction) that can optionally be exchanged/controlled with RemoveComponent and InsertComponent.
When designing my own classes, are there ways of directly expressing these kinds of ownership issues within the language? Or are there any best practices/naming conventions that are common amongst developers?
Not exactly on topic, but certainly related: there are multiple 'singleton' design pattern implementations that enforce single-time creation of objects.
Regarding naming conventions: the term "Owner" (or "OwnsObjects" from your own example) definitely expresses ownership in the sense that that owner will take care of destruction when necessary. Thus a button created with a form as owner (the single parameter of the button's default constructor) needs no manual destruction.
The concepts in Delphi differ from C++ in many occasions. Both languages are third generation, but Delphi likes to work on a higher level of abstraction than C++. For instance, Delphi supports pointers but they are rarely used when campared to the concept of reference, which is not precisely the same one as in C++.
In Delphi, object variables are in fact references (or in a lower level of abstraction, they are pointers). In C++, when you declare an object variable, the constructor is invokated imediatly, in Delphi it´s not and you have to call it in a given moment, what will allocate memory and run the constructor. So, the memory management of objects in C++ and Delphi are conditionated to different life cycles.
All this was said just to tell you that the memory management design style in Delphi is different than C++. That´s why Delphi doesn´t have any helper class that does precisely what you want. However, Delphi provides a concept named Interfaces, that do not exist in C++ (at least, it didn´t when I used to work with C++, ages ago). Interfaces are similar to an abstract class in the sense they do not have code. You have to provide a class implementor to a interface and that class will provide the code. However, Interfaces provide a reference-count memory management that, I believe, is close to what your are looking for.
So, my answer to you is: the closest language construct that Delphi has to offer you in terms of memory management that can be used to your purposes is Interfaces. So, I suggest that you study it at least a bit to get your own conclusions.

Is it safe to use C++ "operator new" rather than CoCreateinstance to create a COM object?

this is probably a noob COM question, but googling this raises more questions than providing answers:
Is it safe to use "operator new" instead of CoCreateInstance for a local COM instance?
What I've done:
I implemented the IOperationsProgressDialog interface
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775368(v=vs.85).aspx
by using public inheritence and thereby also implemented the IUnknown interface.
I created an instance via "new RecyclerProgressCallback" and put it into a COM-Ptr for life-time management. "RecyclerProgressCallback" is the name of my derived class.
I'm using this instance in IFileOperation::SetProgressDialog
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775803(v=vs.85).aspx
Summary: My approach "seems" to work, but I don't trust it, there's just too much disconcerting information around COM object creation to rely on the observable behavior only.
Are there any subtle risks, fallacies or other problems? Thanks!
I've even put them on the stack. Andrey's answer (now deleted) incorrectly suggested that it is unsafe, because you bypass COM reference counting. This is faulty reasoning. COM doesn't count references; it delegates the responsibility to you. You have to call delete, or free(), or whatever your language uses, after COM calls your Release method on its last interface. The important word is after. Not when, because you're not obliged to do so immediately.
Similarly, CoCreateInstance is a long detour because COM is language-neutral and doesn't know whether an object must be created with malloc or new. You do, so just bypass the whole COM logic.
It depends what exactly you are instantiating. When you are supposed to provide a COM pointer noone asks you whether it is instantiated with COM API, or new, or it can sometimes be even object on stack (provided that you manage to ensure it is not destroyed on stack before all references are released).
So the answer is yes, you can use new and it would be fine. However, it should be a valid COM interface anyway, it should implement reference counting and QueryInterface the way COM objects do.
CoCreateInstance API will look at the registry find the module that match specified CLSID, load it and the through a mechanism(it depend whether your code is DLL or EXE) it will call some functions to create your object. So for your code in order to make CoCreateInstance to work, you should write a class that implement IClassFactory interface of COM and register it in the registry and then call CoCreateInstance that do a couple of extra work with your code to at least do your lovely operator new, then yes of course it is safe. In general it is always safe to call operator new of implementation of source interfaces(interfaces that only declared for callback) in your code and this is also the preferred way.
This will work fine. This is how a COM server would typically create its objects internally (at least one written in C++). From your point of view, the RecyclerProgressCallback class is just some C++ code. You can treat it as any other class in your program.
That being said, COM is a minefield of subtle gotchas. I can't promise that you won't encounter problems with your class, but I can assure you that those problems will be unrelated to your use of operator new.
It's generally not safe, not just because of reference counting but also because of marshalling: the class may have a threading model that requires marshalling. CoCreateInstance will create a proxy and stub if that's the case, whereas new will not.

C++ Memory management

I've learned in College that you always have to free your unused Objects but not how you actually do it. For example structuring your code right and so on.
Are there any general rules on how to handle pointers in C++?
I'm currently not allowed to use boost. I have to stick to pure c++ because the framework I'm using forbids any use of generics.
I have worked with the embedded Symbian OS, which had an excellent system in place for this, based entirely on developer conventions.
Only one object will ever own a pointer. By default this is the creator.
Ownership can be passed on. To indicate passing of ownership, the object is passed as a pointer in the method signature (e.g. void Foo(Bar *zonk);).
The owner will decide when to delete the object.
To pass an object to a method just for use, the object is passed as a reference in the method signature (e.g. void Foo(Bat &zonk);).
Non-owner classes may store references (never pointers) to objects they are given only when they can be certain that the owner will not destroy it during use.
Basically, if a class simply uses something, it uses a reference. If a class owns something, it uses a pointer.
This worked beautifully and was a pleasure to use. Memory issues were very rare.
Rules:
Wherever possible, use a
smart pointer. Boost has some
good ones.
If you
can't use a smart pointer, null out
your pointer after deleting it.
Never work anywhere that won't let you use rule 1.
If someone disallows rule 1, remember that if you grab someone else's code, change the variable names and delete the copyright notices, no-one will ever notice. Unless it's a school project, where they actually check for that kind of shenanigans with quite sophisticated tools. See also, this question.
I would add another rule here:
Don't new/delete an object when an automatic object will do just fine.
We have found that programmers who are new to C++, or programmers coming over from languages like Java, seem to learn about new and then obsessively use it whenever they want to create any object, regardless of the context. This is especially pernicious when an object is created locally within a function purely to do something useful. Using new in this way can be detrimental to performance and can make it all too easy to introduce silly memory leaks when the corresponding delete is forgotten. Yes, smart pointers can help with the latter but it won't solve the performance issues (assuming that new/delete or an equivalent is used behind the scenes). Interestingly (well, maybe), we have found that delete often tends to be more expensive than new when using Visual C++.
Some of this confusion also comes from the fact that functions they call might take pointers, or even smart pointers, as arguments (when references would perhaps be better/clearer). This makes them think that they need to "create" a pointer (a lot of people seem to think that this is what new does) to be able to pass a pointer to a function. Clearly, this requires some rules about how APIs are written to make calling conventions as unambiguous as possible, which are reinforced with clear comments supplied with the function prototype.
In the general case (resource management, where resource is not necessarily memory), you need to be familiar with the RAII pattern. This is one of the most important pieces of information for C++ developers.
In general, avoid allocating from the heap unless you have to. If you have to, use reference counting for objects that are long-lived and need to be shared between diverse parts of your code.
Sometimes you need to allocate objects dynamically, but they will only be used within a certain span of time. For example, in a previous project I needed to create a complex in-memory representation of a database schema -- basically a complex cyclic graph of objects. However, the graph was only needed for the duration of a database connection, after which all the nodes could be freed in one shot. In this kind of scenario, a good pattern to use is something I call the "local GC idiom." I'm not sure if it has an "official" name, as it's something I've only seen in my own code, and in Cocoa (see NSAutoreleasePool in Apple's Cocoa reference).
In a nutshell, you create a "collector" object that keeps pointers to the temporary objects that you allocate using new. It is usually tied to some scope in your program, either a static scope (e.g. -- as a stack-allocated object that implements the RAII idiom) or a dynamic one (e.g. -- tied to the lifetime of a database connection, as in my previous project). When the "collector" object is freed, its destructor frees all of the objects that it points to.
Also, like DrPizza I think the restriction to not use templates is too harsh. However, having done a lot of development on ancient versions of Solaris, AIX, and HP-UX (just recently - yes, these platforms are still alive in the Fortune 50), I can tell you that if you really care about portability, you should use templates as little as possible. Using them for containers and smart pointers ought to be ok, though (it worked for me). Without templates the technique I described is more painful to implement. It would require that all objects managed by the "collector" derive from a common base class.
G'day,
I'd suggest reading the relevant sections of "Effective C++" by Scott Meyers. Easy to read and he covers some interesting gotchas to trap the unwary.
I'm also intrigued by the lack of templates. So no STL or Boost. Wow.
BTW Getting people to agree on conventions is an excellent idea. As is getting everyone to agree on conventions for OOD. BTW The latest edition of Effective C++ doesn't have the excellent chapter about OOD conventions that the first edition had which is a pity, e.g. conventions such as public virtual inheritance always models an "isa" relationship.
Rob
When you have to use manage memory
manually, make sure you call delete
in the same
scope/function/class/module, which
ever applies first, e.g.:
Let the caller of a function allocate the memory that is filled by it,
do not return new'ed pointers.
Always call delete in the same exe/dll as you called new in, because otherwise you may have problems with heap corruptions (different incompatible runtime libraries).
you could derive everything from some base class that implement smart pointer like functionality (using ref()/unref() methods and a counter.
All points highlighted by #Timbo are important when designing that base class.