C ++ передает указатель по ссылке и присваивает значение по умолчанию - PullRequest
6 голосов
/ 02 декабря 2009

Я хотел бы передать указатель по ссылке на функцию, чтобы я мог реально изменить адрес, на который указывает переданный указатель, и я хотел бы присвоить этому аргументу значение по умолчанию.

как то так:

в декларации

void myFunc(SomeType* &var=NULL);

и определение:

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

    if(someCondition)
        var=NULL;
}

такой, что вызываемый абонент может решить, хочет ли он вызвать функцию с одним аргументом или без аргумента. И так, что если он решит передать аргумент и выполнит someCondition, переданный указатель впоследствии будет указывать на NULL

однако - если я попытаюсь сделать это так, я получу:

Ошибка C2440: «аргумент по умолчанию»: «int» нельзя преобразовать в «SomeType * &»

Спасибо за помощь!

Ответы [ 5 ]

14 голосов
/ 02 декабря 2009

NULL не является lvalue - его нельзя передать по ссылке. Это все равно что передать 4 в функцию, которая ожидает int&.

Часть 'int' объясняется тем, что NULL является макроопределением 0.

Ваша лучшая ставка будет использовать указатель для передачи указателя по ссылке, то есть двойной указатель. Затем, если параметр NULL, ничего не было передано. Если нет, то это адрес указателя, который следует изменить [чтобы он указывал на NULL, если выполняется некоторое условие].

7 голосов
/ 02 декабря 2009

Сообщение об ошибке говорит само за себя: вы передаете целое число вместо ссылки на указатель на SomeType. Чтобы сделать то, что вы хотите, вы можете использовать указатель на указатель на SomeType:

void myFunc(SomeType** var=NULL);

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

    if(var!=NULL && someCondition)
        *var=NULL;
}
2 голосов
/ 17 августа 2011

Почему бы просто не перегрузить функцию?

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 голосов
/ 02 декабря 2009

Хорошо, я понимаю, почему вы делаете это с точки зрения использования мозга C ++, но действительно ли вы это сделаете в производственном коде?Это похоже на невероятно туманную технику с побочными эффектами, если смотреть на код как коллегу 1 год спустя.Задумывались ли вы об использовании двух отдельных функций с понятными именами: одна возвращает указатель, а другая выполняет любую другую необходимую работу?

2 голосов
/ 02 декабря 2009

Вы также можете рассмотреть возможность использования boost :: option (не самый простой код, который вы можете использовать, но опция есть):

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...