A simple replacement for Boost :: Optional for using nullable types in C ++ projects

The article tells the story of how the author was scared by the monstrous Boost and how he came up with his little nullable bike. Perhaps the article will be useful to those who want to use simple nullable types in their project without using Boost, which meet the not-so-simple requirements given in the article.

So, when I started supporting one relatively large project on MFC that implements a thin billing client, I found that every time when it is necessary to pass NULL to the database, there is additional code containing a check like this (conditionally):

//...
void CSomeClass::someFunction(double variable)
{
//...
if (variable == 0)
{
    db->addValue(NULL);
}
else
{
    db->addValue(variable);
}
//…

When I was faced with the need to implement a new feature in this project, which requires reading and writing NULL values, I immediately wanted to build in the project support for nullable types, which would provide a simple and safe solution in terms of memory leaks for creating them, assigning them different values, copying and transferring to those ready-made functions that accept a pointer to a value in memory as input.

Until now, I have not had to use the Boost library, but I heard about it and thought: "Great, it's time to feel it." Moreover, the “google” on the topic “c ++ nullable type” somehow hints at Boost :: Optional.

However, I quickly realized that Boost :: Optional did not suit me (and / or did not like it). Firstly, its study and connection to the project was not included in the estimation of the time spent on the task, and secondly, I realized (maybe I was wrong here) that I would get problems when converting from Boost :: Optional to the usual “pointer” type C ( at least, it will not look very nice in the code), in other words, I was completely unprepared for the fact that I would encounter difficulties for me in its use. Maybe the whole point is that I had Jeff Alger’s read book “C ++ for real programmers” behind my back, there were various solutions in my head for implementing all kinds of smart (and not so) pointers and operator overloading, and therefore I didn’t understand why to implement a nullable type, which I saw as pretty simple (for my needs), I need a monster like Boost :: Optional.

And my needs are as follows (immediately using my nullable bike as an example):

class FooModel 
{
public:
     NullableType intParam;
};
FooModel* model = new FooModel(); // Хочу, чтобы по-умолчанию моя nullable-переменная была равна NULL
bool resBool = model->intParam == nullptr; // Хочу уметь сравнивать значение моей переменной с NULL
model->intParam = 654; // Хочу “просто взять и присвоить” ей значение соотв. типа
resBool = model->intParam == nullptr; // Хочу иметь возможность “просто взять и приравнять” её NULL, не думая об утечках памяти
NullableType globIntParam1 = model->intParam; // Хочу простого копирования значений, не думая об утечках и выделении памяти
int* intVarPtr1 = new int(23); // Хочу полной совместимости с нативными C-указателями
int* intVarPtr2 = NULL;
model->intParam = intVarPtr1; // Хочу чтобы и так можно было
model->intParam = intVarPtr2; // и так тоже. (Корректная передача значения в функции, принимающие указатель)
NullableType globIntParam2(intVarPtr); // А заодно пусть будет и конструктор копирования

Do I need a simple wrapper over the built-in simple C-types, allowing me to assign them a NULL value, something like int? or double? in C #, without the support of nulling anything. (Just in case, I’ll say that there can be no talk of using features of C ++ 11 and higher). A little googling, I found a couple of similar implementations, but I was confused by the lack of all the features I needed and I wrote my own implementation of a nullable wrapper.

If I'm right, then something similar is needed in many C ++ projects. Therefore, it is hard to imagine that Google still does not give a simple solution on this issue.

My wrapper has a problem - it cannot be thoughtlessly used with strings, because when initializing a string “wrapped” in it with a NULL value, you need to somehow make it so that when you try to convert to string, get an empty string from NULL. In the comments to the sources there is a quick fix option (checked in gcc and clang, everything is ok), but not everyone may like it. You can also solve this problem for MFC privately by adding support for CString, which are used in it instead of the usual string, but I did not do this so as not to bind it to MFC, and until now I just did not need to write a NULL value in the database instead of an empty string.

I’m going to give various suggestions and criticisms, maybe I didn’t put enough effort into finding a ready-made simple solution to this problem.

The source code for the described nullable class is here .

Also popular now: