Почему я не могу передать адрес в качестве ссылки? - PullRequest
4 голосов
/ 10 января 2012

У меня есть функция, которая принимает указатель в качестве ссылочного аргумента, но я не могу передать &my_variable в функцию.Я получаю ошибку cannot convert parameter from my_class* to my_class*&, используя VS2010.

Почему это не разрешено?

class my_class
{
public:
    my_class();
    my_class(my_class* &parent);
};

-

int main()
{
    my_class a;
    my_class b(&a);                   // Not legal

    // ---
    my_class a;
    my_class* a_ptr = &a;
    my_class b(a);                    // Legal

    // ---
    my_class* a = new my_class;
    my_class* b = new my_class(a);    // Legal
}

Ответы [ 3 ]

10 голосов
/ 10 января 2012

Результатом выражения адреса является значение. Следовательно, вы не можете связать его со ссылкой на nonconst.

Это также не имеет смысла. Это все равно что сказать int a; &a = 12; Очевидно, что вы не можете изменить адрес переменной a.

Вместо этого вы хотите это:

int a;
int * p = &a;
mutate_me(p);    // declared as mutate_me(int * &);

Если функция не нуждается в мутации указателя, передайте ее либо по const-reference, либо по значению.

1 голос
/ 10 января 2012

Неофициально, метод, ожидающий параметр по ссылке, ожидает, что ему будет передано что-то, что может быть юридически помещено в левую часть оператора присваивания (иногда называемого «lvalue»).

int main()
{
    my_class a;
    my_class b(&a);                   // Not legal: &a = 0; would be illegal because you can't change an address of a variable.

    // ---
    my_class a;
    my_class* a_ptr = &a;
    my_class b(a_ptr);                    // Legal: You've declared a_ptr on the stack and its value (what it points to) can be changed. The address of a_ptr would not be changeable though.

    // ---
    my_class* a = new my_class;
    my_class* b = new my_class(a);    // Legal: Again, this is on the stack and `a` could point to something else, but its own address won't be changed.
}

В этом случае стоит указать, что в большинстве случаев передача указателя по значению стоит недорого и будет работать. Если вам действительно нужно, чтобы указатель был изменяемым (передаваемым по ссылке), тогда вам нужно передать lvalue.

Другим вариантом является ссылка const. Тогда я считаю, что вы можете передать rvalues просто отлично.

1 голос
/ 10 января 2012

Подумайте о ситуации, когда вы пишете что-то вроде

void foo(bar*& ptr) {
  ptr = new bar;
}

bar b;
foo(&b);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...