C++ 复古新手:地址引用
C++ retro newbie: address references
所以,在离开 C++ 20 年后,我又回到了它。我一辈子都无法解决这个问题。我正在 [at work] 类 工作,我传递的是地址引用,而不是指针引用。下面这个小 foo() 示例,为什么我不能 return NULL 或 nullptr?我违反了什么规则我忘了?
int& foo(int &i)
{
if (i > 10)
{
// or return nullptr;
return NULL;
}
return i;
}
在 C++ 中,NULL 是实现定义的,但通常它只是整数:
#define NULL 0
或
#define NULL nullptr
// 自 C++11
在这两种情况下,错误都是类型不匹配:
error: invalid initialization of non-const reference of type 'int&'
from an rvalue of type 'int'
#define NULL 0
^
why cannot I not return NULL or nullptr?
因为您已将函数声明为 return 对 int 的 引用。引用必须始终 "point" 到实际存在的 int
。因此,nullptr
不是有效值。 (空指针不能转换为对 int 的引用,它只能转换为 pointer to int。)
解决方案一:
将函数声明为 return 指向 int 的指针:
int* foo(int &i)
{
if (i > 10)
{
return nullptr; // or NULL, or 0. (Since NULL is a macro expanding to `0` or `nullptr` anyway.)
}
return &i; // Return the address of i, aka a pointer to i.
}
方案二:
声明一个在语义上等同于return空值的 int 值。
int& foo(int &i)
{
static int nullValue = 0;
if (i > 10)
{
// or return nullptr;
return nullValue;
}
return i;
}
现在每次 i > 10
为真时,函数将 return 引用等于 0
的静态局部变量(如果需要,您可以更改实际值) .
当然,如果return i
return的值与nullValue
相同,那么函数调用者无法知道函数return是否引用了nullValue
或一些实际值 i
.
没有"address references"这样的东西。有"references",和指针不同。 C++ 引用是许多其他语言(例如 C 或 Java)所没有的非常强大的语言功能。
最好将引用描述为现有对象的不同名称。或者更好的是,作为对象本身。 引用是对象。
这根本不像指针。指针 本身就是一个对象 恰好指向其他东西(或什么都没有)。
They do it for performance reasons.
不,他们没有。如果他们这样说,那就没有意义了。您不使用引用来提高性能(至少不是非常量引用),而是使用它们来确保正确性。
int& foo(int &i)
{
if (i > 10)
{
// or return nullptr;
return NULL;
}
return i;
}
没有"null references"这样的东西。请记住,引用是对象。那么你这里的foo
函数returns其实就是对象本身。不是指向它的指针,不是它的地址,而是对象本身。
NULL
或 nullptr
是什么对象?这没有意义。不可能有一个什么都不是的对象。
如果您需要在您的业务逻辑中有一个特殊的 "nothing" 状态,那么您可以使用类似 boost::optional
的东西。或者也许你真的想要一个指针,毕竟。这取决于。
rather than pointer references.
存在指针引用,但它们与您的示例无关。
这是一个指针引用:
int main()
{
int x = 0;
int* ptr = &x;
int*& y = ptr; // "y" is now a different name for "ptr"
}
您可能 find this 回答有见地。
简短回答: 在 C++ 中,引用永远不能是 NULL
(或 NULL
的任何版本,如 nullptr
),因为它必须取消引用总是安全的。
不允许空引用 - "A reference shall be initialized to refer to a valid object or function. [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bitfield. ]"。资料来源:http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29
所以,在离开 C++ 20 年后,我又回到了它。我一辈子都无法解决这个问题。我正在 [at work] 类 工作,我传递的是地址引用,而不是指针引用。下面这个小 foo() 示例,为什么我不能 return NULL 或 nullptr?我违反了什么规则我忘了?
int& foo(int &i)
{
if (i > 10)
{
// or return nullptr;
return NULL;
}
return i;
}
在 C++ 中,NULL 是实现定义的,但通常它只是整数:
#define NULL 0
或
#define NULL nullptr
// 自 C++11
在这两种情况下,错误都是类型不匹配:
error: invalid initialization of non-const reference of type 'int&'
from an rvalue of type 'int'
#define NULL 0
^
why cannot I not return NULL or nullptr?
因为您已将函数声明为 return 对 int 的 引用。引用必须始终 "point" 到实际存在的 int
。因此,nullptr
不是有效值。 (空指针不能转换为对 int 的引用,它只能转换为 pointer to int。)
解决方案一:
将函数声明为 return 指向 int 的指针:
int* foo(int &i)
{
if (i > 10)
{
return nullptr; // or NULL, or 0. (Since NULL is a macro expanding to `0` or `nullptr` anyway.)
}
return &i; // Return the address of i, aka a pointer to i.
}
方案二:
声明一个在语义上等同于return空值的 int 值。
int& foo(int &i)
{
static int nullValue = 0;
if (i > 10)
{
// or return nullptr;
return nullValue;
}
return i;
}
现在每次 i > 10
为真时,函数将 return 引用等于 0
的静态局部变量(如果需要,您可以更改实际值) .
当然,如果return i
return的值与nullValue
相同,那么函数调用者无法知道函数return是否引用了nullValue
或一些实际值 i
.
没有"address references"这样的东西。有"references",和指针不同。 C++ 引用是许多其他语言(例如 C 或 Java)所没有的非常强大的语言功能。
最好将引用描述为现有对象的不同名称。或者更好的是,作为对象本身。 引用是对象。
这根本不像指针。指针 本身就是一个对象 恰好指向其他东西(或什么都没有)。
They do it for performance reasons.
不,他们没有。如果他们这样说,那就没有意义了。您不使用引用来提高性能(至少不是非常量引用),而是使用它们来确保正确性。
int& foo(int &i) { if (i > 10) { // or return nullptr; return NULL; } return i; }
没有"null references"这样的东西。请记住,引用是对象。那么你这里的foo
函数returns其实就是对象本身。不是指向它的指针,不是它的地址,而是对象本身。
NULL
或 nullptr
是什么对象?这没有意义。不可能有一个什么都不是的对象。
如果您需要在您的业务逻辑中有一个特殊的 "nothing" 状态,那么您可以使用类似 boost::optional
的东西。或者也许你真的想要一个指针,毕竟。这取决于。
rather than pointer references.
存在指针引用,但它们与您的示例无关。
这是一个指针引用:
int main()
{
int x = 0;
int* ptr = &x;
int*& y = ptr; // "y" is now a different name for "ptr"
}
您可能 find this 回答有见地。
简短回答: 在 C++ 中,引用永远不能是 NULL
(或 NULL
的任何版本,如 nullptr
),因为它必须取消引用总是安全的。
不允许空引用 - "A reference shall be initialized to refer to a valid object or function. [Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bitfield. ]"。资料来源:http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29