我尝试以下代码,并得到一个编译错误。
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) 函数?
我尝试以下代码,并得到一个编译错误。
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) 函数?
传递给非const
引用的指针变量必须与引用匹配相同的数据类型。该函数期望一个A*
指针的引用,所以这就是你必须给它的。如果你有一个B*
指针开始,A*
首先将它分配给一个变量(因为B
派生自A
):
B* pB = ...;
A* pA = pB;
f(pA);
但是如果函数修改了它传递的指针,它会修改pA
not 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
. 轰隆隆!
在您的代码中,函数 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;
}