Я пытаюсь следующий код, и получаю ошибку компиляции.
class A {};
class B : public A {};
void f(A*& p) {}
int
main()
{
B* pB;
f(pB); // cannot convert argument 1 from 'B *' to 'A *&'
return 0;
}
Как обойти, чтобы f (pB) вызывал f (A *)&п) функция?
Переменная-указатель, переданная неconst
ссылка должна соответствовать тому же типу данных, что и ссылка. Функция ожидает ссылку на A*
указатель, так что это то, что вы должны дать. Если у тебя есть B*
указатель для начала, назначьте его A*
переменная первая (так как B
происходит от A
):
B* pB = ...;
A* pA = pB;
f(pA);
Но если функция изменяет переданный указатель, она изменит pA
не pB
, Если вам нужно изменить pB
вместо этого вам придется пересмотреть свой дизайн.
Если вы квалифицируете параметр как const
, тем самым гарантирующий тот f
не будет изменять его, тогда нет проблем:
void f(A* const & p) { /* Compiles fine */ }
Вы не можете сделать это, и вот почему. Предположим, это было разрешено и f()
выглядело так:
void f(A*& p) { p = new A(); }
Теперь вы делаете это:
B* pB;
f(pB);
когда f()
возвращается, pB
будет указывать на A
, Kaboom!
В вашем коде функция f берет «указатель на класс A по ссылке».
Вы не можете динамически преобразовать «ссылку на A-указатель» в «ссылку на B-указатель»: тогда как класс B является производным от класса A (и, следовательно, B-ссылка динамически преобразуется в A-ссылку) B-указатель все еще не является производным классом A-указателя. Я думаю, что ваша попытка смешать указатели и ссылки не имеет большого смысла.
Вы должны просто изменить свой код в
class A {};
class B : public A {};
void f( A & p) {}
int
main()
{
B pB;
f(pB); // you are now passing a B object by reference
return 0;
}
Предыдущие ответы очень хорошо объяснили, почему ваш код не может работать.
Если вы хотите найти обходной путь для вашей проблемы, вы можете использовать функцию шаблона foo:
class A {
public:
A() {}
A(A*) {}
virtual ~A() {}
};
class B : public A {
public:
B () {}
B(B*) {}
virtual ~B() {}
};
template <class A, class B>
B* foo(A* p) {
//do something related to p - delete, or something
B* p_new = new B(dynamic_cast <B*> (p));
return p_new;
}
int
main()
{
B* pB = new B;
pB = foo <A,B> (pB);
return 0;
}