4

我正在查看我在旧代码库中发现的东西,我很困惑。

这是一个函数定义:

void vUpdateSequenceDetailsAndIncrement(
            const CallEvent& roCPEvent,
            const CallInfo& roCallInfo,
            BOOL bCreationEvent);

这里被称为:

vUpdateSequenceDetailsAndIncrement(roCPEvent, NULL, FALSE);

这里NULL被直接传递给引用参数roCallInfo。该函数最终调用:

vTimeChange(*pSeqDetails, roCPEvent, roCallInfo);

定义:

void vTimeChange(const SequenceDetails& roSequenceDetails,
        const CallEvent& roCPEvent,
        const CallInfo& roCallInfo)

再次将可能为 NULL 的值传递给roCallInfo. 我认为NULL不能作为参考传递?有谁知道 VC++ 4.x 是否有某种问题使这种代码没问题?如果 NULL 可以作为引用传递,那么在 vTimeChange 中会发生这样的事情:

roCallInfo.getCallStartTime(); 

这不是以与我要做的方式相同的方式取消引用 NULL

CallInfo * info = NULL;
info->getCallStartTime();

? 无论如何,我可能会在那里放置一个警卫,如果不需要,让编译器将其删除,但我很想深入了解这是如何发生的!

谢谢。

4

3 回答 3

8

取决于在 VC 4.2 中如何定义 NULL

如果只是

#define NULL 0 

然后你实际上得到了这个:

vUpdateSequenceDetailsAndIncrement(roCPEvent, CallInfo(0), FALSE);

并将 CallInfo 类型的 temp var 的引用传递给函数(如果 CallInfo 具有兼容的 ctor)

于 2011-09-07T17:23:23.027 回答
5

我认为NULL不能作为参考传递?

有效的引用不能为空,但无效的引用可以为空。
你这里有一个Invalid Reference

引用不能为 null 的事实并不意味着引用在某种程度上比指针更安全,正如您在本例中看到的那样。程序可能导致无效引用的方式有很多种,您的代码就是这样一个例子。

参考 Wikipedia:
实际上也有 areference可以开始的方式invalid。因为引用通常实现为底层指针,所以在指针解引用表达式上初始化引用通常由编译器实现为从指针到引用的底层指针的简单赋值。因此,如果您有一个NULL指针或指向内存中无效位置的指针,您实际上将有一个指向 NULL 或无效位置的引用。C++ 纯粹主义者会争辩说,从技术上讲,取消引用 NULL 或无效指针无论如何都会导致未定义的行为,因此这并不违反上面的断言,即引用不能为空或指向内存中的任意位置. 但是,这忽略了这样一个事实,即在这种情况下,底层实现只是简单地执行了一次“赋值”,并没有对所涉及的内存位置进行访问,因此这种引用的初始化通常不会引起问题,程序员必须注意在实际程序中存在事实上的“无效”引用的可能性。

使用无效引用 roSequenceDetails最终会导致未定义的行为。

于 2011-09-07T17:22:03.507 回答
0

如果为 null ,则表达式*pSeqDetails会导致未定义的行为。pSeqDetails任何事情都有可能发生。大多数实现不进行任何特定的检查。在您执行实际需要该对象的操作之前,您的代码似乎可以正常工作,然后它将失败。但是一个实现可能会导致它立即失败。

于 2011-09-07T17:18:03.243 回答