The Windows Component Object Model (COM) system is a massive, massive dependency. How big and complex is it? Well, I usually list it on my resume as a separate line item.
When you first decide to incorporate COM-aware code into your application, you’re signing up to import an entire ecosystem of macros, interfaces, types, headers, class-specific smart pointers… and headaches. Naturally, it makes sense to try and segregate that mess from the rest of your pristine code. Encapsulate it in the smallest container possible. In general – when I require functionality from a COM type – I immediately abstract it away, behind a more user-friendly, ‘standard’ C++ helper class or interface.
If you do it right, consumers of your code never need to know it’s utilizing COM at all. Continue reading “Abstracting away Windows COM dependencies”
When protecting shared resources across multiple threads, developers will generally reach for a “mutex.” As a refresher; a mutex is a type of object which ‘protects’ a resource, ensuring it is only accessed by a single consumer at a time; all other consumers are forced to wait in line. They must wait for the original consumer to release the mutex, before someone else can use it.
Think of a mutex like a key; you can only access the ‘locked’ resource as long as you’re holding the key. If someone else holds the key, you have to wait for them to put it down before you can pick it up.
With this in mind, it should go without saying that a mutex should generally be held only for the minimum amount of time absolutely necessary. When acquiring a mutex, users are encouraged to quickly finish their work so they can release the mutex to another consumer who might be waiting in line.
To some extent, this depends greatly on the shared ‘resource’ in question. For a shared queue, it’s easy to quickly acquire a mutex, ‘pop’ the top item off the stack, and release the mutex – all without the user’s awareness. For other resources however, consumers may need to hold a mutex for an extended period of time, through a series of complex operations.
For example: a connected “instrument” – such as a robot arm, or stepper motor – may need to be ‘reserved’ by a consumer for an extended period of time. It may need to perform many complex operations before the consumer is ready to release the mutex for someone else to use.
In cases like these, it is dangerous to rely on the consumer of a resource to reliably lock and unlock the mutex themselves. It would be so much more convenient and safe, if we could somehow package the resource and the mutex together, ensuring that one is always included with the other.
Enter the “lease” object.
Continue reading “Protecting Shared Resources with a Temporary “Lease””
A basic tenet of modern C++ programming; for leak-free code, you must use
std::shared_ptr by default. Any time you allocate memory, it should be placed immediately into a smart pointer. Ideally, the smart pointer’s initialization will also occur on the same line of code as the memory allocation:
// Allocate memory in the unique_ptr’s constructor
unique_ptr<int> myPtr(new int(12));
// Alternatively, use the standard make_unique helper method, and the ‘auto’ keyword;
auto myPtr2 = make_unique<int>(12);
There are times, however, when your application must interact with – *gasp!* – legacy APIs. Legacy APIs which might allocate memory before handing off ownership to you, the client. This article will discuss clean, convenient ways to ensure that memory allocated from a ‘legacy’ API is reliably placed into a smart pointer.
Continue reading “Using std::unique_ptr with “Legacy” output APIs”
Single-instance classes can be a useful tool, in object-oriented programming. Generally, singleton classes are discouraged and categorized as a likely code smell, because they too closely resemble global variables. They can lead to tightly-coupled code and hidden dependencies, which makes unit testing difficult.
That remains good advice; if you can avoid using singletons, do so.
There are, however, valid reasons to use a singleton. Ironically, they are especially useful for unit testing projects which need to interact with ‘statically-oriented’ legacy code libraries – libraries which don’t contain objects or classes, and therefore can’t be easily mocked in unit tests. In these cases, a singleton class can help ‘wrap’ the static functions into an object-oriented interface, making your application code easier to test. This post describes the general strategy used for this approach. Continue reading “A Valid Use-Case For Singletons”
Being able to arbitrarily ‘look up’ or fetch an element from a collection is a critical tool in almost all C++ applications – or any programming language, for that matter. Typically, in C++, this common paradigm manifests through the use of an
std::map<TKey, TItem> or an
std::unordered_map<TKey, TItem> . When your lookup ‘key’ is a simple, built-in type – such as an enum, int or string – everything just ‘works,’ because those simple types have built-in comparison operators.
Trivial keys can have limited usefulness, however. More often than not, we need more complex lookup keys, in the form of aggregate types. This post describes some tricks you can use to easily create aggregate types and reduce boilerplate code. Continue reading “Easier comparison operators with std::tie”