我尝试以下代码,并获得编译错误。
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 *& p)函数?
答案 0 :(得分:5)
传递给非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 */ }
答案 1 :(得分:4)
你不能这样做,这就是原因。假设它被允许并且f()
看起来像这样:
void f(A*& p) { p = new A(); }
现在你这样做:
B* pB;
f(pB);
f()
返回时,pB
将指向A
。 KABOOM!
答案 2 :(得分:0)
在你的代码中,函数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;
}
答案 3 :(得分: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;
}