在C++中表示可为null成员的最佳方式
Best way to represent Nullable member in C++?
可能重复:
C++中可为空的值
在C++中表示可为null成员的最佳方式是什么?
在C#中,我们可以使用Nullable<T>
类型。非常需要这样的数据类型,因为并非所有数据都可以具有有意义的值。这是一种非常重要的数据类型,@Jon Skeet花了整整一章的时间,跨越了27页,在他出色的著作《深度C#》中只描述了Nullable<T>
。
一个简单的例子可以是Person
类1,定义为:
struct Person
{
std::string Name;
DateTime Birth;
DateTime Death;
//...
};
由于一个人总是有生日,所以上述类别的Birth
成员总是会有一些有意义的值。但是Death
呢?如果这个人还活着,它应该有什么价值?在C#中,该成员可以声明为Nullable<DataTime>
2,如果该人还活着,则可以将其分配为null
。
在C++中,解决这个问题的最佳方法是什么?到目前为止,我只想到一个解决方案:将成员声明为指针:
DataTime *Death;
现在,当人活着时,它的值可以是nullptr
。但它强制对死者使用new
,因为它将具有一些有效值。这反过来意味着不能依赖编译器生成的默认副本语义代码。程序员必须按照第三条规则(C++03(编写复制构造函数、复制赋值、析构函数,或者在C++11中编写第五条规则。
那么,对于这个问题,我们有什么比让它成为指针更好、更优雅的解决方案吗?
1.其他例子包括关系数据库表,因为在许多DBMS中,列可以为null
2.这也有一个简写。可以写入与CCD_ 11完全相同的的CCD_
您可以查看Boost。可选:
struct Person
{
std::string Name;
DateTime Birth;
boost::optional<DateTime> Death;
//...
};
- 您的
Death
一开始是"未初始化"的 - 然后可以使用
=
为其指定一个值,如Death = myDateTime
- 当使用
Death.is_initialized()
时,可以使用Death.get()
- 用
Death.reset()
重新初始化
然而,对于像这样的简单情况,通常认为只选择自己的公然哨兵值更连贯,比如DateTime
为"0000-00-00 00:00:00"。
取决于DateTime
——就像@Tomalak在他的回答中所说的,boost::optional<>
是一个通用的解决方案。但是,例如,如果您的DateTime
是boost::posix_time::ptime
,则已经支持特殊值(例如not_a_date_time
或pos_infin
(-您可以使用这些值。
我参与的每个项目都有某种Fallible
、Maybe
或Nullable
模板类。(实际名称往往反映应用程序首先需要它作为返回值:CCD_ 28,Nullable
为数据库建模等(引入CCD_ 30;遗憾的是,他们使用隐式转换而不是isValid
(命名(函数,这会显著地导致可读性较差的代码(到了我会避免的程度,除了可能实现我自己的Maybe
(。
由于死亡不太可能发生在出生前的任何时间,您也可以在最初将其设置为出生-1,并在实际事件中更改。在更常见的术语中,您可能会将birth-1称为sentinel值或占位符值。您也可以选择一个足够低的常数值,以免被误认为是真实值,但前提是您对数据有一定的了解。
你可以做之前众多程序员所做的事情!使用特定值作为"不存在"。。。例如,我听说"2000年1月1日"很常见:-(:-(出于互操作性的原因,你可以使用"2038年1月19日03:14:07 UTC":-((如果不清楚的话,这是个笑话。我指的是Y2K问题和Y2038问题。我展示了使用"特殊"日期作为状态的问题…类似11-11-11和类似的事情(
DataTime
的最大/最小值可能更正确:-(它仍然是错误的,因为您将"状态"与"值"混合在一起。最好在C++中重建Nullable
类型(最后这很容易:一个模板化的类,带有用于null/not null的bool和T字段(
我会创建一个表示null值的静态成员,然后将死亡日期的地址与静态对象的地址进行比较。如果它们相等,则值为NULL。
- 在派生类中使用基类的私有成员变量的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- 可以具有不同基成员实现的类的最佳实现
- 删除类成员的动态分配内存的最佳方法是什么
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- std::使用类成员函数创建线程 - 最佳实践
- 使用相同方法但不同成员类型构建类的最佳方法
- 在函数中使用 const 引用参数访问函数中成员的最佳实践 C++.
- 返回可能在C++中分配在堆栈上的成员时,最佳指针/引用类型是什么
- 成员变量的初始化必须延迟。此类的最佳设计选择是什么?
- 在抽象基类中与抽象类成员合作的最佳方法
- 具有许多成员变量的课程的最佳实践
- 访问成员变量或访问成员函数是最佳选择
- 在C++中将迭代器存储为类成员的最佳实践
- 获取私有实例变量容器成员值的最佳方式
- C++是修改这些对象的向量中所有对象的给定成员的最佳方法
- 复制包含STL成员(如vector)的C++结构的最佳方法是什么
- 最佳实践:访问向量中具有不同成员变量和方法的派生类
- 私有类成员延迟初始化的最佳做法
- 组织专用成员 Vector<Vector 接口的最佳方式<Type>>