I'm creating a database access layer in native C++, and I'm looking at ways to support NULL values. Here is what I have so far:
class CNullValue { public: static CNullValue Null() { static CNullValue nv; return nv; } }; template<class T> class CNullableT { public: CNullableT(CNullValue &v) : m_Value(T()), m_IsNull(true) { } CNullableT(T value) : m_Value(value), m_IsNull(false) { } bool IsNull() { return m_IsNull; } T GetValue() { return m_Value; } private: T m_Value; bool m_IsNull; };
This is how I'll have to define functions:
void StoredProc(int i, CNullableT<int> j) { ...connect to database ...if j.IsNull pass null to database etc }
And I call it like this:
sp.StoredProc(1, 2);
or
sp.StoredProc(3, CNullValue::Null());
I was just wondering if there was a better way than this. In particular I don't like the singleton-like object of CNullValue with the statics. I'd prefer to just do
sp.StoredProc(3, CNullValue);
or something similar. How do others solve this problem?
You typically use a nullable value type when you need to represent the undefined value of an underlying value type. For example, a Boolean, or bool , variable can only be either true or false . However, in some applications a variable value can be undefined or missing.
Recently a client asked me what is the difference between NULL and 0 values in Tableau. The answer to that is rather simple: a NULL means that there is no value, we're looking at a blank/empty cell, and 0 means the value itself is 0.
Technically a null value is a reference (called a pointer in some languages) to an empty area of memory. Reference variables (variables that contain an address for data rather than the data itself) are always nullable , which means they are automatically capable of having a null value.
Nullable types are a feature of some programming languages which allow a value to be set to the special value NULL instead of the usual possible values of the data type.
Boost.Optional probably does what you need.
boost::none
takes the place of your CNullValue::Null()
. Since it's a value rather than a member function call, you can do using boost::none;
if you like, for brevity. It has a conversion to bool
instead of IsNull
, and operator*
instead of GetValue
, so you'd do:
void writeToDB(boost::optional<int> optional_int) { if (optional_int) { pass *optional_int to database; } else { pass null to database; } }
But what you've come up with is essentially the same design, I think.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With