Я создаю слой доступа к базе данных в собственном C++, и я смотрю на способы поддерживать Нулевые значения. Вот то, что я имею до сих пор:
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;
};
Это - то, как я должен буду определить функции:
void StoredProc(int i, CNullableT<int> j)
{
...connect to database
...if j.IsNull pass null to database etc
}
И я называю его как это:
sp.StoredProc(1, 2);
или
sp.StoredProc(3, CNullValue::Null());
Я просто задавался вопросом, был ли лучший путь, чем это. В особенности мне не нравится подобный одиночному элементу объект CNullValue с помехами. Я предпочел бы просто делать
sp.StoredProc(3, CNullValue);
или что-то подобное. Как другие решают эту проблему?
Boost.Optional , вероятно, сделает то, что вам нужно.
boost :: none
заменяет ваш CNullValue :: Null ()
. Поскольку это значение, а не вызов функции-члена, вы можете сделать , используя boost :: none;
, если хотите, для краткости. Он имеет преобразование в bool
вместо IsNull
и оператор *
вместо GetValue
, поэтому вы должны:
void writeToDB(boost::optional<int> optional_int) {
if (optional_int) {
pass *optional_int to database;
} else {
pass null to database;
}
}
Но я думаю, что вы придумали, по сути, тот же дизайн.
Замените IsNull
на HasValue
, и вы получите тип .NET Nullable .
Конечно .. это C ++. Почему бы просто не использовать указатель на «примитивный» тип?