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, and hand 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 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”