无法从'DerivedClass *'转换为'BaseClass *&'

时间:2014-05-23 15:38:15

标签: c++ reference polymorphism pass-by-reference upcasting

我尝试以下代码,并获得编译错误。

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)函数?

4 个答案:

答案 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;
}