如何将派生类的指针传递给对基类的指针的引用?

时间:2019-07-05 12:56:07

标签: c++

这是示例代码。

class BaseClass {
};

class DerivedClass : public BaseClass {
};

int Foo(BaseClass*& ptr) {
}

DerivedClass* ptr_to_derived;

//following will not work
Foo(ptr_to_derived);

我无法编译上面的代码,并且错误消息为“ can't convert DerivedClass* to BaseClass*&”。那么如何将ptr_to_derived传递给Foo?

4 个答案:

答案 0 :(得分:6)

错误消息很清楚:

  

错误:类型的非常量引用无效的初始化   类型为“ BaseClass*&”的右值“ BaseClass*

由于Foo通过非常量引用获取指针,因此无法将其传递给右值。从DerivedClassBaseClass的隐式转换,当您将其传递到Foo时,会得到错误所抱怨的右值。

您可以从派生的指针创建基本指针,然后传递该指针:

DerivedClass* ptr_to_derived;
BaseClass* ptr_derived_base = ptr_to_derived;

Foo(ptr_derived_base);

答案 1 :(得分:1)

你不能那样做。

您可以做的是将其转换为指向基的指针,将转换后的指针存储在某个位置(例如变量),然后通过左值引用传递该指针。该引用不能引用派生的指针。像这样:

BaseClass* ptr_to_base = ptr_to_derived;
Foo(ptr_to_base);

但是,最好通过值传递指针以避免这种麻烦。或者最好在足够的情况下甚至将引用而不是指针传递给基址。像这样:

int Foo(BaseClass& ref)

与此您可以致电:

DerivedClass1 d1;
DerivedClass2 d2;
Foo(d1);
Foo(d2);

// or with pointers
DerivedClass1* d1_ptr = &d1;
DerivedClass2* d2_ptr = &d2;
Foo(*d1_ptr);
Foo(*d2_ptr);

答案 2 :(得分:1)

问题是Foo可能会修改传递的指向基础的指针。例如:

class OtherDerivedClass : public BaseClass {
};

OtherDerivedClass* ptr_to_other_derived = ...;

void Foo(BaseClass*& ptr)
{
    ptr = ptr_to_other_derived;
}

如果您可以将Foo称为ptr_to_derived,您会怎么办?现在ptr_to_derived应该不是指向DerivedClass而是指向OtherDerivedClass对象吗?在每个级别上都是错误的。

解决方案1::不允许Foo修改指针。要么按值传递:

void Foo(BaseClass* ptr)

或通过const-ref:

void Foo(const BaseClass*& ptr)

解决方案2:创建指向Foo可以修改的指向基础的变量。

BaseClass* ptr_to_base = ptr_to_derived;
foo(ptr_to_base);

这当然会使ptr_to_derived保持不变。 C ++不允许您传递一个临时表达式(这是从DerivedClass*BaseClass*的转换将返回的结果),因为Foo再次声明它将修改该指针,而更改后的临时变量将只是被丢弃。通常这是一个错误。当然,您仍然可以决定不关心ptr_to_base可能对Foo所做的更改。

答案 3 :(得分:1)

出于合理原因这是非法的,请查看以下代码:

class BaseClass {};

class DerivedClass :public BaseClass {};
class DerivedClass2 :public BaseClass {};

DerivedClass2 derived2;

void Foo(BaseClass*& ptr) {
    ptr = &derived2; // Legal.
}

DerivedClass* ptr_to_derived = nullptr;

然后,如果合法,Foo(ptr_to_derived)会使ptr_to_derived成为无关的DerivedClass2,这是错误的。