假设引用作为指针传递是否有效

时间:2012-11-20 09:23:30

标签: c++ visual-studio-2010 reference arguments

我有一个像这样定义的函数:

void doSomethingWithCustomer (const Customer &customer);

我的一位开发人员称之为:

Customer *customer = order.getCustomer();
doSomethingWithCustomer (*customer);

不幸的是,如果订单没有绑定到客户,getCustomer方法可以返回nullptr。 如果getCustomer返回nullptr,那么应用程序在调用doSomethingWithCustomer时不会崩溃,而是在使用客户引用的函数内崩溃。

当然,写这个的正确方法是首先检查客户不是nullptr,然后如果我们有一个有效的客户则调用该函数。 通常我们期望如果一个函数/方法有一个引用参数,那么调用者会检查它的有效性(这里不是这种情况),而不是函数本身检查参数。

我知道Visual Studio 2010(和早期版本)通过实际传递指针来传递引用,但我想知道这是否在C ++标准中的某处显示。我们可以假设引用始终作为指针传递(个人而言,我不会依赖于此,但知道这一点很有趣)?

是否有可能告诉Visual Studio在传递引用时,它应该首先自动取消引用它并在调用时崩溃而不是更深一些(在调试版本中执行此操作可能就足够了)?

6 个答案:

答案 0 :(得分:4)

  

假设引用作为指针传递是否有效?

不,不是。
该标准并未强制要求以指针的形式实现引用。

如何实际实现引用是标准遗漏的实现细节,供实现决定。它仅描述了Reference中的预期行为,其中一个是标准符合程序中永远不能为NULL的引用。

如果你的函数参数有时候应该是NULL,那么你应该将它作为指针传递。

答案 1 :(得分:1)

没有。它是完全实现的定义。

出于诊断目的,我创建了一个验证参数的小容器类型。然后,您将声明函数/方法:

void doSomethingWithCustomer(const t_nonnull<const Customer>& pCustomer);

t_nonnull类型在构造时验证参数。但是,我发现越来越频繁地使用引用更有用(IOW,在这种情况下不要返回指针 - 只是当客户不存在时才认为访问客户是错误的)。

答案 2 :(得分:1)

行为未定义。这意味着您不能依赖任何特定的方式来发现错误。一个好的编译器可能能够在编译时警告你,而另一个可能会完全掩盖错误,具体取决于你如何使用变量。您有责任确保引用永远不会为NULL。

答案 3 :(得分:1)

这是不可观察的,而且无关紧要。使用此代码的程序具有未定义的行为,因为它取消引用空指针。

答案 4 :(得分:0)

引用可能在内部使用指针实现(就像在Java中发生的那样)。但低于2的差异在他们之间至关重要:

  1. 默认情况下,指针可以重新绑定到另一个对象。然而 reference与已初始化的对象具有永久绑定
  2. 指针可以指定为0,但引用不能
  3. 类似地,T&相当于T* const

    您无需通知编译器有关引用变量的信息,因为这可能是您自己发生的。

    void foo(T&);
    
    T t, *p = 0;
    foo(t); // the only way to pass reference
    foo(*p); // the only way to pass reference
    

答案 5 :(得分:0)

正如其他人所说的那样,该标准没有强制如何实施参考。要尽早捕获“作为引用传递的dereferenced NULL”错误,您可以在函数内执行此操作:

void doSomethingWithCustomer (const Customer &customer)
{
  assert(&customer);
  //... rest of function
}