C++传递指针的引用并赋予默认值

6
我希望将一个指针通过引用传递给一个函数,这样我就可以实际更改传递的指针所指向的地址,并且我想为该参数指定一个默认值。
类似这样:
在声明中:
void myFunc(SomeType* &var=NULL);

并且这是定义:
void MyClass::myFunc(SomeType* &var){
    if(var!=NULL)
        (*var)=(*someOtherPointer);

    if(someCondition)
        var=NULL;
}

这样调用者可以决定是否使用一个参数或不使用参数来调用函数。如果他决定传递参数,并且某个条件成立,那么传递的指针在之后将指向NULL。

但是,如果我像这样尝试,就会出现以下错误:

错误C2440:“默认参数”:无法将“int”转换为“SomeType *&”

感谢您的帮助!

5个回答

14

NULL不是lvalue - 它不能通过引用传递。这就像向期望 int& 的函数传递 4

'int' 部分是因为 NULL 是一个宏 - 定义为 0

最好的方法是使用指针通过引用传递指针,即双指针。然后,如果参数是 NULL,则没有传递任何内容。如果不是,则应修改指向 NULL(如果一些条件成立)的指针的地址。


1
另一个选择是使用boost::optional(无意冒犯)。 - David Rodríguez - dribeas
9
或者重载该函数,以提供一个无参版本。 - Pavel Minaev

7
错误信息已经说明了问题:您正在传递一个整数,而不是一个指向SomeType指针的引用。为了实现您想要的功能,您可以使用指向指针的指针。
void myFunc(SomeType** var=NULL);

void MyClass::myFunc(SomeType** var){
    if(var!=NULL && *var!=NULL)
        (**var)=(*someOtherPointer);

    if(var!=NULL && someCondition)
        *var=NULL;
}

除非“someCondition”包括“var!= NULL”,否则您刚刚接受了一个取消引用空指针的答案。这可能不是您想要的。 - imaginaryboy
另外,请注意使用(**var)=(*someOtherPointer)实际上会执行对象复制。如果你只想进行指针复制,你可能想要使用(*var)=(someOtherPointer)。 - Thought

2
为什么不直接重载函数呢?
void myFunc() {
   //whatever logic should happen if a null pointer is passed in
}

void myFunc(SomeType* &var) {
   if(var!=NULL) {
     (*var)=(*someOtherPointer);
   }

   if(someCondition) {
        var=NULL;
   }
}

2
您也可以考虑使用boost::optional(这不是您可以使用的最简单的代码,但该选项可用):
void f( boost::optional<int&> r = boost::optional<int&>() )
{
   if ( r ) *r = 5;
}
int main()
{
   int x = 0;
   f( x ); std::cout << x << std::endl; // 5, it did change the value
   f(); // compiler will default to an empty optional<int&> object
}

2

好的,我理解您想从 C++ 编程技术角度来练习,但您真的会在生产环境中这样做吗?当同事一年后再看代码时,这似乎是一种非常模糊、具有副作用的技术。您是否考虑过使用两个明确命名的分离函数,一个返回指针,另一个执行其他必要的工作?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接