unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
或者:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
IOW:有没有任何理由选择一个而不是另一个?
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
或者:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
我的经验法则是:
如果您想要进行指针算术运算(例如,递增指针地址以浏览数组)或者必须传递一个NULL指针,请使用指针。
否则,请使用引用。
我真的认为建立以下函数调用编码准则会对你有益:
像其他地方一样,始终正确使用 const
。
const
说明符之外,其他所有内容都必须带有它。只有在当前上下文中值为0/NULL时才通过指针传递值。
理由1:作为 调用者,您知道无论传入什么,它都必须处于可用状态。
理由2:作为 被调用者,您知道传入的任何值都是可用的。因此,不需要对该值进行 NULL 检查或错误处理。
理由3:如果可能,请始终在编译时捕获错误。理由1和2将受到 编译器强制执行。
如果函数参数是输出值,则通过引用传递它。
仅在值是 POD (Plain old Datastructure)、足够小(存储器方面)或以其他方式足够便宜(时间方面)复制时,才选择 "按值传递" 而不是 "按 const 引用传递"。
std::vector<>
。 - Johann Gerell这最终还是主观的。到目前为止的讨论很有用,但我认为这没有一个正确或决定性的答案。很多情况下都要取决于样式指南和您当时的需求。
虽然指针具有一些不同的功能(无论是否可以为空),但输出参数最大的实际区别纯粹在于语法上。例如,Google的C ++样式指南(https://google.github.io/styleguide/cppguide.html#Reference_Arguments)规定只能使用指针作为输出参数,并且只允许使用const引用。原因在于可读性:具有值语法的东西不应具有指针语义。我并不是说这一定是对或错,但我认为这里的重点在于这是一个样式问题,而不是正确性问题。
指针
一个当前不指向有效内存位置的指针被赋予空值(即零)。
BaseType* ptrBaseType;
BaseType objBaseType;
ptrBaseType = &objBaseType;
&是一个一元运算符,它返回其操作数的内存地址。
解引用运算符(*)用于访问指针所指向变量中存储的值。
int nVar = 7;
int* ptrVar = &nVar;
int nVar2 = *ptrVar;
参考资料
引用 (&) 就像是一个现有变量的别名。
引用 (&) 就像是一个常量指针,会自动解引用。
通常在函数参数列表和函数返回值中使用。
引用在创建时必须被初始化。
一旦引用被初始化为一个对象,就不能更改为另一个对象的引用。
你不能拥有 NULL 引用。
const 引用可以引用一个 const int。它使用一个临时变量,其值等于 const 常量的值。
int i = 3; //integer declaration
int * pi = &i; //pi points to the integer i
int& ri = i; //ri is refers to integer i – creation of reference and initialization
如果您要修改变量的值,应该传递指针。尽管从技术上讲,传递引用或指针是相同的,但在您的用例中传递指针更易读,因为它“广告”了函数将更改该值的事实。
const
或非const
引用接受,但是您可以看到参数是通过&x
还是x
传递的,并使用该约定来编码参数是否有可能被修改。(也就是说,在某些情况下,您需要传递一个const
指针,因此约定只是一个提示。可以说,怀疑某些东西可能被修改而实际上不会被修改比认为不会被修改而实际上会被修改更加安全。) - Tony Delroy// Sample method using optional as input parameter
void PrintOptional(const boost::optional<std::string>& optional_str)
{
if (optional_str)
{
cout << *optional_str << std::endl;
}
else
{
cout << "(no string)" << std::endl;
}
}
// Sample method using optional as return value
boost::optional<int> ReturnOptional(bool return_nothing)
{
if (return_nothing)
{
return boost::optional<int>();
}
return boost::optional<int>(42);
}
引用是一个隐式指针。基本上,你可以改变引用所指向的值,但你不能改变引用指向其他东西。因此,我的建议是:如果你只想改变参数的值,请将其作为引用传递;但如果你需要改变参数指向不同对象,则使用指针传递。
指针:
nullptr
(或 NULL
)。&
,
明确表明您正在修改对象。引用:
&
。这有时被认为是不好的,
因为您必须去函数的实现中查看参数是否被修改。