使用引用相对于使用指针的优势是否证明偶尔"null-references"是合理的?
Do the advantages of using references over using pointers justify occasional "null-references"?
我目前正在设计一个大致如下所示的类层次结构:
struct Protocol
{
// Pass lower-layer protocol as a reference.
Protocol(Protocol & inLLProtocol) :
mLLProtocol(inLLProtocol)
{
}
// A protocol "always" has a LLProtocol.
Protocol & mLLProtocol;
};
struct Layer1Protocol : Protocol
{
// This is the "bottom" protocol, so I pass a fake reference.
Layer1Protocol() : Protocol(*static_cast<Protocol*>(nullptr)) {}
};
IIRC 将引用绑定到*nullptr
是安全的,只要从不访问引用。因此,现在我有责任以这样的方式设计我的 Layer1Protocol 类来防止这种情况。
我喜欢这种方法,因为我确保所有用户协议实例都将引用其各自的下层协议(Layer1Protocol 是例外,但它是核心库的一部分)。我认为这比使用指针更可取,因为一旦引入了指针,就可以传递空指针,然后可能需要在运行时进行检查,结果是大量的指针检查代码和偶尔的错误。
你认为我基于参考的方法可以辩护吗?还是使用空引用总是不好的做法?
IIRC 将引用绑定到 *nullptr 是安全的,只要从不访问引用。
不,取消引用nullptr
始终是未定义的行为。在正确的程序中不能有"空引用"。
编写*static_cast<Protocol*>(nullptr)
是取消引用nullptr
,它调用未定义的行为。你永远不能那样做。结果可以是墨菲觉得的任何事情。这可能是你所说的"空引用",但也可能是你(男性,AFAIK)怀孕了,而程序就像你取消引用了一个有效的指针一样工作。
因此,严格来说,没有"空引用"。只是有未定义的行为。
要么你的协议类总是不可避免地需要一个较低级别的协议,在这种情况下,你不能nullptr
传递它(甚至不能伪装在引用中)。或者它不需要一直使用较低级别的协议,并且必须检查它是否有协议才能访问它,在这种情况下,指针可以更好地实现您的设计约束。
您的方法与使用指针的等效方法有何不同,除了语法之外,除了指针方法与引用方法不同,不调用 UB 的事实?
如果您正在使用引用以避免必须检查空指针,但随后传递(非法)空引用,那么您已经否定了引用的优势。现在,您的引用可能突然为 null,因此您可能需要检查该条件,就像使用指针一样。
如果,正如你所说,你可以保证这些空引用都不会被取消引用 - 好吧,如果你使用指针,同样的保证将成立。
长话短说:指针不是要不惜一切代价避免的。如果遇到可能发生空值的情况,则需要使用指针 -- 句点。您似乎担心必须在任何地方检查空指针(大概是通过断言),但在大多数体系结构上,MMU 无论如何都会阻止您取消引用空指针 - 这实际上几乎和断言一样好。
您可能想查看 boost 中的"可选"类模板(我相信)。它允许您传递对象,但也允许您指定您故意没有以比原始指针更安全的方式提供任何数据。
这不是我自己特别喜欢的东西,但你可能会发现它符合你的要求。
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 如何在 c++ 中'NULL'字符串
- c++使用foreach使数组为null
- 当使用通配符和null指针调用函数时,对输出的说明
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 如何在映射中返回null
- 为什么返回 NULL 不会破坏函数?
- 构造函数中的 QQuickItem 父项 null
- 检查字符串是否"null" C++
- fopen 在 gdb 中返回 NULL
- what(): basic_string::_M_construct null not valid
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 为什么在排序链表上的这种合并实现总是将两个列表都设置为 NULL,而只有一个应该设置一个列表?
- 为什么要从main()返回NULL?
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 当目标指针不是基类的类型时,为什么允许dynamic_cast为多态类生成 null 指针?
- 是否有通用方法可以找到任何以 null 结尾的字符串的长度?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 使用 curl_easy_cleanup(curl) 时收到未经处理的 NULL 异常
- 使用引用相对于使用指针的优势是否证明偶尔"null-references"是合理的?